// ============================================================
// Pastagem — Capacidade de Lotação · dados e cálculos
// Modelo CORRIGIDO (igual ao app): Fazenda > Seção > Módulo > Piquete.
// Dois processos distintos:
//   • Entrada/Saída  → lote ENTRA/SAI de um MÓDULO. Define a lotação (carga × dias).
//   • Movimentação   → RODÍZIO do lote entre PIQUETES do mesmo módulo (manejo).
//                      NÃO altera a lotação do módulo.
// Status do módulo é DERIVADO: tem lote → Ocupado; sem lote → Disponível.
// "Indisponível" (reforma/ILP/manutenção) → fase posterior (stub).
// ============================================================
(function () {
  const HOJE = new Date(2026, 5, 18) // 18/06/2026

  // ---- Categoria do Lote (1 UA = 450 kg PV) — fator UA manual ----
  const CATEGORIAS = [
    { nome: 'Desmama 8–12 meses', fator: 0.56 },
    { nome: 'Novilhas 13–18 meses', fator: 0.78 },
    { nome: 'Novilhas em Monta', fator: 0.89 },
    { nome: 'Novilhas Cheias', fator: 1.0 },
    { nome: 'Vaca Solteira', fator: 1.1 },
    { nome: 'Vaca Solteira Entourada', fator: 1.28 },
    { nome: 'Vaca Parida', fator: 1.28 },
    { nome: 'Vaca Parida Entourada', fator: 1.55 },
    { nome: 'Touro', fator: 1.55 },
    { nome: 'Rufião', fator: 1.0 },
  ]
  const FATOR = Object.fromEntries(CATEGORIAS.map((c) => [c.nome, c.fator]))

  // ---- Tipos de capim — lista global, só o nome ----
  const CAPINS = [
    { nome: 'Brachiaria Marandu' },
    { nome: 'Mombaça' },
    { nome: 'Massai' },
    { nome: 'Tanzânia' },
  ]

  const FAZENDAS = ['Mateira', 'Guanabara', 'Paranapanema', 'Serena']

  // ---- Piquetes — lista GLOBAL (A–H e 1–20), associada aos módulos ----
  const PIQUETES_GLOBAL = ['ABCDEFGH'.split(''), Array.from({ length: 20 }, (_, i) => String(i + 1))].flat()

  // ---- Tipos de Evento de Pasto — lista GLOBAL (eventos agronômicos) ----
  const EVENTOS_PASTO = [
    'Aplicação Adubo - Uréia',
    'Aplicação Adubo - Nitrato',
    'Aplicação Adubo - Formulado',
    'Aplicação Adubo - Orgânico',
    'Aplicação Inseticida',
    'Aplicação Herbicida',
    'Roçada',
  ]

  // ---- Datas (helpers) ------------------------------------------------------
  const z = (n) => String(n).padStart(2, '0')
  const fmtBR = (d) => `${z(d.getDate())}/${z(d.getMonth() + 1)}/${d.getFullYear()}`
  const parseBR = (s) => { const [d, m, y] = s.split('/').map(Number); return new Date(y, m - 1, d) }
  const addDays = (d, n) => new Date(d.getTime() + n * 86400000)
  const diasEntre = (dataBR) => Math.round((HOJE - parseBR(dataBR)) / 86400000)

  // ---- Estrutura: Módulos por fazenda/seção --------------------------------
  // M(nome, areaHa, capim, lote)  ·  lote = [obs(legado), categoria, qtd, entrada 'DD/MM/AAAA'] | null
  const M = (nome, area, capim, lote) => ({ nome, area, capim, lote })

  const ESTRUTURA = [
    {
      fazenda: 'Mateira',
      secoes: [
        { nome: 'Sede', modulos: [
          M('1', 42, 'Brachiaria Marandu', ['', 'Vaca Parida', 62, '24/05/2026']),
          M('2', 38, 'Brachiaria Marandu', ['', 'Novilhas Cheias', 70, '02/06/2026']),
          M('3', 55, 'Mombaça', ['', 'Novilhas 13–18 meses', 120, '11/05/2026']),
          M('4', 28, 'Brachiaria Marandu', null),
          M('6B', 64, 'Massai', ['', 'Vaca Solteira', 118, '30/04/2026']),
          M('7', 31, 'Brachiaria Marandu', null),
        ] },
        { nome: 'Baixada', modulos: [
          M('B1', 96, 'Mombaça', ['', 'Touro', 22, '15/05/2026']),
          M('B2', 73, 'Brachiaria Marandu', ['', 'Vaca Parida Entourada', 84, '28/05/2026']),
          M('B3', 49, 'Brachiaria Marandu', ['', 'Desmama 8–12 meses', 96, '20/05/2026']),
          M('B4', 58, 'Massai', null),
        ] },
      ],
    },
    {
      fazenda: 'Guanabara',
      secoes: [
        { nome: 'Guanabara', modulos: [
          M('Pivot', 34, 'Mombaça', ['', 'Novilhas Cheias', 96, '07/06/2026']),
          M('9', 47, 'Brachiaria Marandu', ['', 'Vaca Solteira Entourada', 70, '12/05/2026']),
          M('10', 52, 'Brachiaria Marandu', ['', 'Novilhas 13–18 meses', 88, '01/06/2026']),
          M('11', 39, 'Massai', null),
          M('12', 61, 'Mombaça', ['', 'Vaca Parida', 102, '18/05/2026']),
        ] },
        { nome: 'Panema', modulos: [
          M('25 MASSAI', 88, 'Massai', ['', 'Novilhas em Monta', 140, '22/05/2026']),
          M('26', 71, 'Brachiaria Marandu', ['', 'Vaca Solteira', 132, '16/04/2026']),
          M('27', 43, 'Brachiaria Marandu', null),
          M('28', 119, 'Tanzânia', ['', 'Novilhas 13–18 meses', 180, '09/05/2026']),
        ] },
        { nome: 'Forma', modulos: [
          M('F1', 66, 'Mombaça', ['', 'Vaca Parida Entourada', 92, '03/06/2026']),
          M('F2', 54, 'Brachiaria Marandu', ['', 'Novilhas Cheias', 74, '26/05/2026']),
          M('F3', 48, 'Brachiaria Marandu', null),
        ] },
      ],
    },
    {
      fazenda: 'Paranapanema',
      secoes: [
        { nome: 'I', modulos: [
          M('P1', 134, 'Tanzânia', ['', 'Novilhas 13–18 meses', 210, '14/05/2026']),
          M('P2', 78, 'Brachiaria Marandu', ['', 'Vaca Solteira', 124, '21/05/2026']),
          M('P3', 92, 'Mombaça', ['', 'Vaca Parida', 168, '06/05/2026']),
          M('P4', 45, 'Brachiaria Marandu', null),
          M('P5', 63, 'Massai', null),
        ] },
        { nome: 'II', modulos: [
          M('P6', 194, 'Tanzânia', ['', 'Novilhas 13–18 meses', 360, '12/05/2026']),
          M('P7', 87, 'Brachiaria Marandu', ['', 'Touro', 26, '19/05/2026']),
          M('P8', 56, 'Brachiaria Marandu', null),
          M('P9', 41, 'Massai', ['', 'Desmama 8–12 meses', 70, '04/06/2026']),
        ] },
      ],
    },
    {
      fazenda: 'Serena',
      secoes: [
        { nome: 'Pivôs', modulos: [
          M('PV1', 36, 'Mombaça', ['', 'Novilhas Cheias', 104, '09/06/2026']),
          M('PV2', 33, 'Mombaça', ['', 'Vaca Parida', 84, '11/06/2026']),
          M('PV3', 35, 'Mombaça', null),
        ] },
        { nome: 'Cerrado', modulos: [
          M('S1', 112, 'Tanzânia', ['', 'Novilhas 13–18 meses', 168, '02/05/2026']),
          M('S2', 74, 'Brachiaria Marandu', ['', 'Vaca Solteira', 96, '23/05/2026']),
          M('S3', 9, 'Brachiaria Marandu', ['', 'Rufião', 14, '30/05/2026']),
          M('S4', 58, 'Massai', null),
        ] },
      ],
    },
  ]

  // ---- Piquetes: cada módulo tem N piquetes (A–H, depois 1–20) --------------
  // Realidade do cliente: nenhum módulo tem menos de 8 piquetes; os grandes chegam a 20.
  const nPiquetes = (area) => Math.max(8, Math.min(20, Math.round(area / 8)))
  const RODIZIO_DIAS = 22 // intervalo típico de rodízio entre piquetes

  // ---- Achatar em lista de módulos + derivar piquete atual / status --------
  let _id = 0
  const MODULOS = []
  ESTRUTURA.forEach((f) => {
    f.secoes.forEach((s) => {
      s.modulos.forEach((mod) => {
        const id = ++_id
        const piquetes = PIQUETES_GLOBAL.slice(0, nPiquetes(mod.area))
        let atual = null
        if (mod.lote) {
          const entrada = mod.lote[3]
          const diasModulo = diasEntre(entrada)
          const r = Math.min(piquetes.length - 1, Math.floor(diasModulo / RODIZIO_DIAS))
          const desdeD = addDays(parseBR(entrada), r * RODIZIO_DIAS)
          atual = {
            categoria: mod.lote[1], qtd: mod.lote[2], entrada, diasModulo,
            piquete: piquetes[r], desde: fmtBR(desdeD), diasPiquete: diasEntre(fmtBR(desdeD)),
            rodizios: r,
          }
        }
        MODULOS.push({
          id, nome: mod.nome, fazenda: f.fazenda, secao: s.nome,
          area: mod.area, capim: mod.capim, piquetes,
          status: atual ? 'ocupado' : 'disponivel',
          atual,
        })
      })
    })
  })

  // ---- Cálculos -------------------------------------------------------------
  const cargaUA = (mod) => (mod.atual ? mod.atual.qtd * (FATOR[mod.atual.categoria] || 0) : 0)

  // Um módulo agrupa vários piquetes e PODE ter mais de um piquete com lote ao mesmo
  // tempo. O modelo web guarda 1 lote/módulo (rodízio); a camada de campo generaliza
  // para N lotes simultâneos em piquetes distintos (demo: P1 e P6 com 2º lote).
  const LOTES_EXTRA = {
    PV1: [{ piquete: 'F', categoria: 'Vaca Parida', qtd: 96, diasPiquete: 12, ua: 106 }],
    PV2: [{ piquete: 'D', categoria: 'Desmama 8–12 meses', qtd: 88, diasPiquete: 7, ua: 40 }],
    P1: [{ piquete: 'F', categoria: 'Vaca Parida', qtd: 96, diasPiquete: 12, ua: 106 }],
    P6: [{ piquete: 'E', categoria: 'Desmama 8–12 meses', qtd: 88, diasPiquete: 7, ua: 40 }],
  }
  // Lotes presentes no módulo (0, 1 ou mais), um por piquete ocupado.
  const lotesDoMod = (mod) => {
    if (!mod || !mod.atual) return []
    const a = mod.atual
    return [{ piquete: a.piquete, categoria: a.categoria, qtd: a.qtd, diasPiquete: a.diasPiquete, ua: cargaUA(mod) }, ...(LOTES_EXTRA[mod.nome] || [])]
  }
  // Lote em um piquete específico (ou null se o piquete está vazio).
  const loteNoPiquete = (mod, p) => (p ? lotesDoMod(mod).find((l) => l.piquete === p) || null : null)

  // Composição do PIQUETE: no campo o time junta lotes de categorias diferentes no mesmo
  // piquete para aproveitar pasto. A maioria dos piquetes segue com 1 categoria; alguns
  // (demo determinística) têm 2 ou 3. Retorna [] quando o piquete está vazio.
  const composicaoNoPiquete = (mod, p) => {
    const l = loteNoPiquete(mod, p)
    if (!l) return []
    const base = [{ categoria: l.categoria, qtd: l.qtd }]
    if (!mod || mod.id % 3 !== 0) return base
    const outras = CATEGORIAS.filter((c) => c.nome !== l.categoria)
    const a = outras[mod.id % outras.length]
    const b = outras[(mod.id + 4) % outras.length]
    const extra = [{ categoria: a.nome, qtd: 20 + (mod.id * 7) % 40 }]
    if (b.nome !== a.nome) extra.push({ categoria: b.nome, qtd: 15 + (mod.id * 5) % 30 })
    return [...base, ...extra]
  }
  const uaDaComposicao = (itens) => (itens || []).reduce((a, i) => a + (i.qtd || 0) * (FATOR[i.categoria] || 0), 0)

  // capacidade de referência (estimativa por área) — só p/ análise sintética
  const estimUA = (area) => area * 1.9
  const capacidadeUA = (mod) => estimUA(mod.area)

  // Status DERIVADO do módulo:
  //   Ocupado      = pelo menos um lote em algum piquete
  //   Sem lote     = todos os piquetes vazios
  //   Indisponível = marcado ativamente pelo usuário no mapa atual (não liberado para uso)
  //   Arquivado    = existia em mapa anterior e não faz parte da estrutura atual;
  //                  não aparece em Lotação atual, só via configuração da fazenda
  const STATUS = {
    ocupado: { key: 'ocupado', label: 'Ocupado', tone: 'danger' },
    disponivel: { key: 'disponivel', label: 'Sem lote', tone: 'info' },
    indisponivel: { key: 'indisponivel', label: 'Indisponível', tone: 'alert' },
    arquivado: { key: 'arquivado', label: 'Arquivado', tone: 'neutral' },
  }

  // ---- Cadastro / configuração das fazendas --------------------------------
  const FAZENDA_META = {
    Mateira:      { cidade: 'Santa Rita do Pardo', uf: 'MS', cep: '79690-000', endereco: 'Rodovia MS-040, km 12', numero: 's/n',  bairro: 'Zona Rural',     complemento: 'Sede administrativa', cnpj: '12.345.678/0001-90', ie: '901.234.567.110', areaProdutiva: 612,  ativa: true },
    Guanabara:    { cidade: 'Paranapoema',         uf: 'PR', cep: '87680-000', endereco: 'Estrada da Baixada',     numero: 's/n',  bairro: 'Gleba Ribeirão', complemento: '',                    cnpj: '12.345.678/0002-70', ie: '901.234.567.292', areaProdutiva: 980,  ativa: true },
    Paranapanema: { cidade: 'Paranapoema',         uf: 'PR', cep: '87680-000', endereco: 'Fazenda Paranapanema',   numero: 'km 8', bairro: 'Zona Rural',     complemento: 'Núcleos I e II',       cnpj: '12.345.678/0003-50', ie: '110.045.678.114', areaProdutiva: 1180, ativa: true },
    Serena:       { cidade: 'Água Clara',          uf: 'MS', cep: '79680-000', endereco: 'Sítio Serena',           numero: 's/n',  bairro: 'Pivôs',          complemento: 'Área irrigada',        cnpj: '12.345.678/0004-31', ie: '110.045.678.220', areaProdutiva: 360,  ativa: false },
  }

  // ---- Setores da fazenda (separam atividades pecuárias) -------------------
  // Setor = recorte da fazenda por atividade (Principal, PO, Equinos, Descarte…).
  // atividades: Cria · Recria · Leite · Engorda · Corte (pode ter nenhuma).
  const SETORES = [
    { fazenda: 'Mateira',      nome: 'Mateira Principal',      atividades: ['Cria'],   ativo: true },
    { fazenda: 'Mateira',      nome: 'Mateira PO',             atividades: ['Cria'],             ativo: true },
    { fazenda: 'Mateira',      nome: 'Mateira Equinos',        atividades: [],                   ativo: true },
    { fazenda: 'Guanabara',    nome: 'Guanabara Principal',    atividades: ['Cria', 'Recria', 'Engorda'], ativo: true },
    { fazenda: 'Guanabara',    nome: 'Guanabara Equinos',      atividades: [],                   ativo: true },
    { fazenda: 'Guanabara',    nome: 'Guanabara Descarte',     atividades: ['Engorda'],          ativo: true },
    { fazenda: 'Guanabara',    nome: 'Guanabara Leiteiras',    atividades: ['Leite'],            ativo: false },
    { fazenda: 'Paranapanema', nome: 'Paranapanema Principal', atividades: ['Cria', 'Recria'],   ativo: true },
    { fazenda: 'Paranapanema', nome: 'Paranapanema PO',        atividades: ['Cria'],             ativo: true },
    { fazenda: 'Paranapanema', nome: 'Paranapanema Equinos',   atividades: [],                   ativo: true },
    { fazenda: 'Serena',       nome: 'Serena Principal',       atividades: ['Leite'],            ativo: false },
  ]

  // Resumo agregado por fazenda
  function secoesDe(fazenda) {
    const out = []
    const byName = {}
    MODULOS.filter((m) => m.fazenda === fazenda).forEach((m) => {
      if (!byName[m.secao]) { byName[m.secao] = { nome: m.secao, modulos: [] }; out.push(byName[m.secao]) }
      byName[m.secao].modulos.push(m)
    })
    out.forEach((s) => { s.area = s.modulos.reduce((a, m) => a + m.area, 0); s.ativa = true })
    return out
  }
  function fazendaResumo(fazenda) {
    const secoes = secoesDe(fazenda)
    return {
      meta: FAZENDA_META[fazenda],
      nSecoes: secoes.length,
      nModulos: secoes.reduce((a, s) => a + s.modulos.length, 0),
      nPiquetes: secoes.reduce((a, s) => a + s.modulos.reduce((b, m) => b + m.piquetes.length, 0), 0),
      areaTotal: secoes.reduce((a, s) => a + s.area, 0),
      animaisAtivos: MODULOS.filter((m) => m.fazenda === fazenda && m.atual).reduce((a, m) => a + m.atual.qtd, 0),
    }
  }

  // ---- Histórico de movimentos: GERADO a partir do estado ------------------
  // tipo: 'entrada' | 'saida' | 'movimentacao'(rodízio entre piquetes do mesmo módulo)
  const OPS = ['Amanda Reis', 'Caíque Souza', 'Gabriele Lima', 'Felipe Tavares', 'Marina Alves']
  const MOTIVOS = ['Venda', 'Abate', 'Dispersão', 'Mortalidade']
  let _mid = 0
  const MOVIMENTOS = []

  MODULOS.forEach((m) => {
    if (m.atual) {
      const a = m.atual
      const entD = parseBR(a.entrada)
      // 1) Entrada no módulo (piquete inicial A)
      MOVIMENTOS.push({ id: ++_mid, tipo: 'entrada', fazenda: m.fazenda, secao: m.secao,
        moduloNome: m.nome, piquete: m.piquetes[0], categoria: a.categoria, qtd: a.qtd,
        data: a.entrada, op: OPS[m.id % OPS.length] })
      // 2) Movimentações internas entre piquetes — NOVO MODELO: cada movimentação
      //    é registrada como uma SAÍDA do piquete de origem + uma ENTRADA no piquete
      //    de destino (dois lançamentos-base; sem vínculo "setinha" no dado).
      //    `interno: true` é apenas dica de exibição (rótulo derivado "movimentação").
      for (let i = 1; i <= a.rodizios; i++) {
        const d = fmtBR(addDays(entD, i * RODIZIO_DIAS))
        const op = OPS[(m.id + i) % OPS.length]
        MOVIMENTOS.push({ id: ++_mid, tipo: 'saida', interno: true, fazenda: m.fazenda, secao: m.secao,
          moduloNome: m.nome, piquete: m.piquetes[i - 1], categoria: a.categoria, qtd: a.qtd, data: d, op })
        MOVIMENTOS.push({ id: ++_mid, tipo: 'entrada', interno: true, fazenda: m.fazenda, secao: m.secao,
          moduloNome: m.nome, piquete: m.piquetes[i], categoria: a.categoria, qtd: a.qtd, data: d, op })
      }
    } else if (m.id % 2 === 0) {
      // Módulo disponível com ciclo encerrado recentemente → registra a SAÍDA
      const dias = 8 + (m.id * 7) % 46
      const d = addDays(HOJE, -dias)
      const cat = CATEGORIAS[(m.id * 3) % CATEGORIAS.length].nome
      const qtd = 40 + (m.id * 11) % 90
      MOVIMENTOS.push({ id: ++_mid, tipo: 'saida', fazenda: m.fazenda, secao: m.secao,
        moduloNome: m.nome, piquete: m.piquetes[(m.id + 1) % m.piquetes.length], categoria: cat, qtd, data: fmtBR(d),
        op: OPS[m.id % OPS.length] })
    }
  })

  // ---- Eventos de pasto (agronômicos) — não alteram a lotação --------------
  // Semeados por módulo; aparecem na timeline do módulo e no log de Movimentações.
  MODULOS.forEach((m) => {
    if (m.id % 3 === 0) {
      const et = EVENTOS_PASTO[(m.id * 2) % EVENTOS_PASTO.length]
      const d = addDays(HOJE, -(1 + (m.id * 5) % 16))
      MOVIMENTOS.push({ id: ++_mid, tipo: 'evento', eventoTipo: et, fazenda: m.fazenda, secao: m.secao,
        moduloNome: m.nome, piquete: m.piquetes[m.id % m.piquetes.length], categoria: '',
        data: fmtBR(d), op: OPS[(m.id + 2) % OPS.length] })
    }
  })
  MOVIMENTOS.sort((x, y) => parseBR(y.data) - parseBR(x.data))

  // ---- Rebanho (amostra de animais p/ integração leve · leitura) -----------
  // Cada animal aponta para o "módulo de pasto" onde está hoje.
  const sexoDe = (cat) => /Touro|Rufião|Desmama|13–18|Recria/.test(cat) ? 'Macho' : 'Fêmea'
  const REBANHO = []
  let _bn = 4120
  MODULOS.filter((m) => m.atual).forEach((m) => {
    const n = Math.min(4, Math.max(2, Math.round(m.atual.qtd / 30)))
    for (let i = 0; i < n; i++) {
      const cat = m.atual.categoria
      REBANHO.push({
        id: REBANHO.length + 1,
        brinco: 'BR' + (++_bn),
        categoria: cat,
        sexo: sexoDe(cat),
        fazenda: m.fazenda,
        moduloPasto: m.nome,
        secao: m.secao,
      })
    }
  })
  // alguns animais sem módulo de pasto atribuído (curral / em trânsito)
  ;['Fêmea', 'Macho'].forEach((sx, i) => {
    REBANHO.push({ id: REBANHO.length + 1, brinco: 'BR' + (++_bn), categoria: i ? 'Touro' : 'Vaca Solteira',
      sexo: sx, fazenda: i ? 'Paranapanema' : 'Mateira', moduloPasto: null, secao: '—' })
  })

  // ---- Série temporal sintética p/ Análise (12 meses × módulo) --------------
  const MESES = ['Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez', 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun']
  const DIAS_MES = [31, 31, 30, 31, 30, 31, 31, 28, 31, 30, 31, 18] // Jun parcial até 18
  function serie(mod) {
    let seed = mod.id * 2654435761 % 2147483647
    const rnd = () => ((seed = (seed * 16807) % 2147483647) / 2147483647)
    const ocup = !!mod.atual
    return MESES.map((_, i) => {
      const base = ocup ? 0.45 + rnd() * 0.55 : rnd() * 0.6
      const boost = mod.capim === 'Mombaça' ? 0.15 : 0
      // módulos vazios hoje → últimos meses tendem a zero
      if (!ocup && i >= 10) return rnd() < 0.6 ? 0 : Math.round(DIAS_MES[i] * rnd() * 0.4)
      return Math.min(DIAS_MES[i], Math.round(DIAS_MES[i] * Math.min(1, base + boost)))
    })
  }

  // ---- Gestão de MÓDULO: indisponibilidade + capim versionado --------------
  // Motivos de indisponibilidade
  const MOTIVOS_INDISP = ['Reforma de pasto', 'ILP', 'Manutenção']
  // Conversão entre input nativo (YYYY-MM-DD) e formato BR (DD/MM/AAAA)
  const isoToBR = (iso) => { if (!iso) return ''; const [y, m, d] = iso.split('-'); return `${d}/${m}/${y}` }
  const brToIso = (br) => { if (!br) return ''; const [d, m, y] = br.split('/'); return `${y}-${m}-${d}` }
  const HOJE_ISO = brToIso(fmtBR(HOJE))

  // Eventos de gestão semeados por módulo (chave = "fazenda|nome")
  //   trocas:  { de, para, data, op }                  → capim versionado
  //   indisp:  { motivo, inicio, fim|null, op, opFim }  → períodos de indisponibilidade
  const EVENTOS_SEED = {
    'Mateira|3':            { trocas: [{ de: 'Brachiaria Marandu', para: 'Mombaça', data: '12/03/2026', op: 'Marina Alves' }] },
    'Mateira|4':            { indisp: [{ motivo: 'Reforma de pasto', inicio: '02/06/2026', fim: '02/08/2026', op: 'Felipe Tavares' }] },
    'Mateira|B4':           { indisp: [{ motivo: 'Manutenção', inicio: '10/03/2026', fim: '28/03/2026', op: 'Caíque Souza', opFim: 'Caíque Souza' }] },
    'Guanabara|Pivot':      { trocas: [{ de: 'Brachiaria Marandu', para: 'Mombaça', data: '03/02/2026', op: 'Amanda Reis' }] },
    'Guanabara|25 MASSAI':  { trocas: [{ de: 'Tanzânia', para: 'Massai', data: '28/01/2026', op: 'Felipe Tavares' }] },
    'Guanabara|11':         { indisp: [{ motivo: 'ILP', inicio: '15/05/2026', fim: '15/08/2026', op: 'Gabriele Lima' }] },
    'Paranapanema|P3':      { trocas: [{ de: 'Brachiaria Marandu', para: 'Mombaça', data: '19/11/2025', op: 'Marina Alves' }] },
    'Paranapanema|P5':      { indisp: [{ motivo: 'Manutenção', inicio: '28/05/2026', fim: '28/06/2026', op: 'Caíque Souza' }] },
    'Serena|S1':            { trocas: [{ de: 'Massai', para: 'Tanzânia', data: '10/12/2025', op: 'Felipe Tavares' }] },
    'Serena|S4':            { indisp: [{ motivo: 'Reforma de pasto', inicio: '05/01/2026', fim: '20/02/2026', op: 'Marina Alves', opFim: 'Marina Alves' }] },
  }

  // Arquivamento de módulo — chave "fazenda|nome". Arquivado = o módulo existia em
  // um mapa anterior da fazenda e NÃO faz parte da estrutura atual (geografia/piquetes
  // mudaram, mesmo com nome igual). Não aparece em Lotação atual — só pela configuração
  // da fazenda — e por isso nenhum módulo do mapa vigente vem arquivado aqui.
  const ARQUIVO_SEED = {}

  // Indisponibilizações em vigor no mapa ATUAL: o usuário marcou o módulo como não
  // liberado para uso. Sempre com previsão de retorno.
  const INDISP_ATIVO_SEED = {
    'Mateira|7':        { inicio: '15/04/2026', fim: '30/11/2026', motivo: 'Reforma de pasto', op: 'Marina Alves' },
    'Guanabara|27':     { inicio: '05/01/2026', fim: '15/10/2026', motivo: 'Reforma de pasto', op: 'Felipe Tavares' },
    'Paranapanema|P8':  { inicio: '20/09/2025', fim: '20/12/2026', motivo: 'Obra de cerca', op: 'Caíque Souza' },
  }

  // Estado mutável inicial (1 registro por módulo) — capim atual + históricos
  function initModState() {
    const st = {}
    MODULOS.forEach((m) => {
      const seed = EVENTOS_SEED[m.fazenda + '|' + m.nome] || {}
      const arq = ARQUIVO_SEED[m.fazenda + '|' + m.nome] || null
      const ind = INDISP_ATIVO_SEED[m.fazenda + '|' + m.nome] || null
      st[m.id] = {
        capim: m.capim,
        trocas: (seed.trocas || []).map((t) => ({ ...t })),
        indisp: [...(seed.indisp || []).map((p) => ({ ...p })), ...(ind ? [{ ...ind }] : [])],
        arquivo: arq ? { ...arq } : null,
      }
    })
    return st
  }

  // Período de indisponibilidade ATIVO agora: já começou e ainda não chegou na data de fim.
  // Quando HOJE alcança a data de fim, o módulo volta a Disponível automaticamente.
  function indispAtivo(rec) {
    if (!rec) return null
    return rec.indisp.find((p) => {
      if (parseBR(p.inicio) > HOJE) return false   // período futuro, ainda não iniciado
      if (!p.fim) return true                       // sem data de fim → ativo até liberar
      return HOJE < parseBR(p.fim)                  // ativo só antes da data de fim
    }) || null
  }

  // Arquivamento em vigor na data de referência: a partir de `fim`, o módulo está arquivado.
  // Antes de `fim`, ainda era ativo (importante para o recorte por período).
  function arquivadoEm(rec, ref) {
    const r = ref || HOJE
    if (!rec || !rec.arquivo) return null
    return parseBR(rec.arquivo.fim) <= r ? rec.arquivo : null
  }
  // Módulo estava ativo em algum momento do período [ini, fim]?
  // Ativo se não arquivado, ou se foi arquivado depois do início do período.
  function ativoNoPeriodo(rec, ini) {
    if (!rec || !rec.arquivo) return true
    return parseBR(rec.arquivo.fim) >= (ini || HOJE)
  }

  // Status DERIVADO ao vivo: Arquivado (fim atingido) > Indisponível (período ativo) > Ocupado > Disponível
  function statusDe(mod, ms, ref) {
    const rec = ms && ms[mod.id]
    if (arquivadoEm(rec, ref)) return 'arquivado'
    if (indispAtivo(rec)) return 'indisponivel'
    return mod.atual ? 'ocupado' : 'disponivel'
  }
  const capimDe = (mod, ms) => (ms && ms[mod.id] ? ms[mod.id].capim : mod.capim)

  // Histórico COMPLETO do módulo: lotes (entrada/saída/rodízio) + eventos de gestão
  function historicoDe(mod, ms) {
    const rec = (ms && ms[mod.id]) || { trocas: [], indisp: [] }
    const items = []
    MOVIMENTOS.filter((x) => x.moduloNome === mod.nome && x.fazenda === mod.fazenda)
      .forEach((mv) => items.push({ ...mv, kind: 'mov' }))
    rec.trocas.forEach((t) => items.push({ kind: 'capim', data: t.data, de: t.de, para: t.para, op: t.op }))
    rec.indisp.forEach((p) => {
      items.push({ kind: 'indisp_ini', data: p.inicio, fim: p.fim, motivo: p.motivo, op: p.op })
      // só mostra "Liberado" quando a data de fim já ocorreu (liberação automática ou antecipada)
      if (p.fim && parseBR(p.fim) <= HOJE) items.push({ kind: 'indisp_fim', data: p.fim, motivo: p.motivo, op: p.opFim || p.op })
    })
    // mudança de mapa: o módulo antigo sai da estrutura ativa (só acessível via
    // configuração da fazenda) — evento próprio, distinto de indisponibilização
    if (rec.arquivo) items.push({ kind: 'arquivo', data: rec.arquivo.fim, op: rec.arquivo.op })
    items.sort((a, b) => parseBR(b.data) - parseBR(a.data) || (b.id || 0) - (a.id || 0))
    return items
  }

  window.PAST = {
    HOJE, HOJE_ISO, CATEGORIAS, FATOR, CAPINS, FAZENDAS, MODULOS, MOVIMENTOS, REBANHO,
    FAZENDA_META, SETORES, secoesDe, fazendaResumo,
    MESES, DIAS_MES, serie, RODIZIO_DIAS,
    cargaUA, capacidadeUA, estimUA, STATUS,
    lotesDoMod, loteNoPiquete, composicaoNoPiquete, uaDaComposicao,
    PIQUETES_GLOBAL, EVENTOS_PASTO,
    MOTIVOS_INDISP, initModState, statusDe, capimDe, historicoDe, indispAtivo, arquivadoEm, ativoNoPeriodo, isoToBR, brToIso,
    fmtBR, parseBR, addDays, diasEntre,
    fmt: (n, d = 0) => new Intl.NumberFormat('de-DE', { minimumFractionDigits: d, maximumFractionDigits: d }).format(n),
    pct: (n) => Math.round(n * 100),
  }
})()
