/* ANISAN — Planejamento de fluxo de caixa, focado em GESTÃO DE PAGAMENTOS.
   Mostra quanto há de capital de giro e quais despesas (Compras / pagamentos
   alimentadas no Painel) ainda faltam pagar no mês escolhido. */

function FluxoCaixa({ unit, period }) {
  const store = window.useStore();
  const data = store.data;
  const D = window.ANISAN_DATA;
  const cons = window.isCons(unit);
  const [monthRef, setMonthRef] = React.useState((window.todayISO ? window.todayISO() : "2026-06-24").slice(0, 7));
  const [escopo, setEscopo] = React.useState("unidade");
  const [payDlg, setPayDlg] = React.useState(null);   // confirmar pagamento
  const [editDlg, setEditDlg] = React.useState(null); // editar lançamento

  React.useEffect(() => { window.lucide && window.lucide.createIcons(); });
  const mobile = window.useIsMobile();

  const escopoEff = cons ? "grupo" : escopo;

  // ---- grade de semanas do mês (segunda a domingo), com dias de transbordo
  // do mês anterior/seguinte. Toda a análise da aba usa [gridStart, gridEnd]. ----
  const toISO = (d) => { const x = new Date(d.getFullYear(), d.getMonth(), d.getDate()); return x.getFullYear() + "-" + String(x.getMonth() + 1).padStart(2, "0") + "-" + String(x.getDate()).padStart(2, "0"); };
  const startOfWeekMon = (d) => { const x = new Date(d); x.setDate(x.getDate() - ((x.getDay() + 6) % 7)); return x; };
  const [mY, mM] = monthRef.split("-").map(Number);
  const firstOfMonth = new Date(mY, mM - 1, 1);
  const lastOfMonth = new Date(mY, mM, 0);
  const gridStartD = startOfWeekMon(firstOfMonth);
  const gridEndD = (() => { const s = startOfWeekMon(lastOfMonth); s.setDate(s.getDate() + 6); return s; })();
  const gridStart = toISO(gridStartD);
  const gridEnd = toISO(gridEndD);
  const weeks = [];
  for (let cur = new Date(gridStartD); cur <= gridEndD; cur.setDate(cur.getDate() + 7)) {
    const days = [];
    for (let i = 0; i < 7; i++) { const d = new Date(cur); d.setDate(d.getDate() + i); days.push({ iso: toISO(d), dia: d.getDate(), outroMes: d.getMonth() !== mM - 1 }); }
    weeks.push(days);
  }

  // capital de giro (saldos reais das contas de giro)
  const giro = escopoEff === "grupo"
    ? D.units.reduce((s, n) => s + window.unitTotals(data, n).giro, 0)
    : window.unitTotals(data, unit).giro;

  // CONTAS A PAGAR: lançamentos avulsos do Painel (data.compras) + despesas
  // FIXAS pendentes, ambos ainda não pagos e com vencimento dentro da grade do
  // mês (inclui transbordo de mês anterior/seguinte), respeitando unidade.
  const baseCompras = escopoEff === "grupo"
    ? window.allCompras(data)
    : (data.compras[unit] || []).map(r => ({ ...r, _u: unit }));

  const fixasPend = window.fixasPendentesRange(data, escopoEff === "grupo" ? window.CONSOLIDADO : unit, gridStart, gridEnd);

  const inGrid = (r) => {
    if (r.paid) return false;
    const iso = window.ddmmToISO(r.venc);
    return iso && iso >= gridStart && iso <= gridEnd;
  };

  const aPagar = [...baseCompras, ...fixasPend]
    .filter(inGrid)
    .sort((a, b) => {
      const ai = window.ddmmToISO(a.venc) || "9999-99-99";
      const bi = window.ddmmToISO(b.venc) || "9999-99-99";
      return ai < bi ? -1 : (ai > bi ? 1 : 0);
    });

  const saidas = aPagar.reduce((s, r) => s + (Number(r.value) || 0), 0);
  const saldoProjetado = giro - saidas;

  // total projetado a pagar por DIA (ISO) — alimenta o gráfico de cada semana
  const byISO = {};
  aPagar.forEach(r => { const iso = window.ddmmToISO(r.venc); if (iso) byISO[iso] = (byISO[iso] || 0) + (Number(r.value) || 0); });
  const weekMax = Math.max(1, ...weeks.map(days => Math.max(...days.map(d => byISO[d.iso] || 0))));

  // Localiza/materializa a instância editável de uma linha (compra ou fixa) e
  // aplica um patch a ela. Para fixas virtuais, materializa o mês primeiro.
  const patchRow = (d, r, patch) => {
    if (r.fixa) {
      const mk = (window.ddmmToISO(r.venc) || window.todayISO()).slice(0, 7);
      if (r.virtual) window.ensureFixasMes(d, mk);
      const arr = (d.despesasFixasLancadas[r._u] || {})[mk] || [];
      const x = arr.find(y => y.fixaId === r.fixaId) || arr.find(y => y.id === r.id);
      if (x) Object.assign(x, patch);
    } else {
      const x = (d.compras[r._u] || []).find(y => y.id === r.id);
      if (x) Object.assign(x, patch);
    }
  };
  const removeRow = (d, r) => {
    if (r.fixa) {
      const mk = (window.ddmmToISO(r.venc) || window.todayISO()).slice(0, 7);
      if (r.virtual) window.ensureFixasMes(d, mk);
      if (d.despesasFixasLancadas[r._u] && d.despesasFixasLancadas[r._u][mk])
        d.despesasFixasLancadas[r._u][mk] = d.despesasFixasLancadas[r._u][mk].filter(y => y.fixaId !== r.fixaId && y.id !== r.id);
    } else {
      d.compras[r._u] = (d.compras[r._u] || []).filter(y => y.id !== r.id);
    }
  };

  // Pagar: abre confirmação (conta de saída + dia do pagamento, pré-preenchido hoje).
  const requestPay = (r) => setPayDlg({ row: r, conta: r.conta || "Cash", data: window.todayISO() });
  const confirmPay = () => { const { row, conta, data: dia } = payDlg; store.set(d => patchRow(d, row, { paid: true, conta: conta || "Cash", pagamento: dia || window.todayISO() }), ["compras", "despesasFixasLancadas"]); setPayDlg(null); };
  const openEdit = (r) => setEditDlg({ row: r, descricao: r.name, valor: String(r.value), venc: window.ddmmToISO(r.venc) || "" });
  const saveEdit = () => { const { row, descricao, valor, venc } = editDlg; store.set(d => patchRow(d, row, { name: descricao || row.name, value: window.parseBRL(valor), venc: venc ? window.dateLabel(venc).slice(0, 5) : row.venc }), ["compras", "despesasFixasLancadas"]); setEditDlg(null); };
  const delRow = (r) => store.set(d => removeRow(d, r), ["compras", "despesasFixasLancadas"]);

  const tiles = [
    { label: "Capital de giro", value: window.BRL(giro), accent: "var(--paper)" },
    { label: "Saídas previstas", value: "− " + window.BRL(saidas), accent: "var(--clay)" },
    { label: "Saldo projetado", value: window.BRL(saldoProjetado), accent: saldoProjetado >= 0 ? "var(--brass)" : "var(--clay)" },
  ];

  return (
    <div style={{ padding: mobile ? "18px 14px 40px" : "26px 32px 48px" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 14, marginBottom: 22 }}>
        <SectionTitle style={{ margin: 0 }}>Planejamento de fluxo de caixa</SectionTitle>
        <div style={{ display: "flex", gap: 12, flexWrap: "wrap", alignItems: "center" }}>
          {!cons && <SegTabs value={escopo} onChange={setEscopo} options={[{ value: "unidade", label: unit }, { value: "grupo", label: "Grupo" }]} />}
          {cons && <Badge accent="var(--brass)" variant="tint">Consolidado · grupo</Badge>}
          <div style={{ display: "flex", alignItems: "center", gap: 8, background: "var(--surface)", border: "1px solid var(--hairline)", borderRadius: "var(--radius-pill)", padding: "5px 6px" }}>
            <button onClick={() => setMonthRef(window.monthShift(monthRef, -1))} style={navMiniFx}><i data-lucide="chevron-left" style={{ width: 16, height: 16, strokeWidth: 1.8 }}></i></button>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: "0.04em", color: "var(--paper)", minWidth: 122, textAlign: "center" }}>{window.monthLabel(monthRef)}</span>
            <button onClick={() => setMonthRef(window.monthShift(monthRef, 1))} style={navMiniFx}><i data-lucide="chevron-right" style={{ width: 16, height: 16, strokeWidth: 1.8 }}></i></button>
          </div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 14, marginBottom: 22 }}>
        {tiles.map((t, i) => (
          <div key={i} style={{ background: "var(--surface)", border: "1px solid var(--hairline)", borderRadius: "var(--radius-tile)", padding: "16px 18px" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.05em", textTransform: "uppercase", color: "var(--muted)", marginBottom: 8 }}>{t.label}</div>
            <div style={{ fontFamily: "var(--font-display)", fontSize: 23, fontWeight: 500, color: t.accent }}>{t.value}</div>
          </div>
        ))}
      </div>

      <div style={{ marginBottom: 24 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap", marginBottom: 14 }}>
          <span style={{ fontFamily: "var(--font-display)", fontSize: 17, fontWeight: 500, color: "var(--paper)" }}>Despesa projetada por dia · semanas de {window.monthLabel(monthRef)}</span>
          <span style={{ display: "flex", alignItems: "center", gap: 14, fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--muted-2)" }}>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}><i style={{ width: 9, height: 9, borderRadius: 2, background: "var(--clay)", display: "inline-block" }}></i>do mês</span>
            <span style={{ display: "flex", alignItems: "center", gap: 6 }}><i style={{ width: 9, height: 9, borderRadius: 2, background: "var(--hairline)", display: "inline-block" }}></i>transbordo (*)</span>
          </span>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {weeks.map((days, wi) => {
            const wd = days.map(d => byISO[d.iso] || 0);
            const wlabels = days.map(d => String(d.dia) + (d.outroMes ? "*" : ""));
            const muted = days.map((d, i) => d.outroMes ? i : -1).filter(i => i >= 0);
            const litIdx = days.map((d, i) => (!d.outroMes && wd[i] > 0) ? i : -1).filter(i => i >= 0);
            const wtotal = wd.reduce((a, b) => a + b, 0);
            const di = window.ANISAN_DATA.diasSemana || ["Seg", "Ter", "Qua", "Qui", "Sex", "Sáb", "Dom"];
            return (
              <Panel key={wi}
                title={"Semana " + (wi + 1) + " · " + days[0].dia + "/" + String((new Date(days[0].iso + "T00:00:00")).getMonth() + 1).padStart(2, "0") + " – " + days[6].dia + "/" + String((new Date(days[6].iso + "T00:00:00")).getMonth() + 1).padStart(2, "0")}
                action={<Badge accent="var(--clay)" variant="tint">{wtotal > 0 ? "− " + window.BRLk(wtotal) : "sem despesas"}</Badge>}>
                <div style={{ display: "flex", justifyContent: "space-around", marginBottom: 6 }}>
                  {di.map((lb, i) => <span key={i} style={{ flex: 1, textAlign: "center", fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--muted-2)" }}>{lb}</span>)}
                </div>
                <BarChart data={wd} labels={wlabels} color="var(--clay)" height={150} max={weekMax} highlight={litIdx} mutedBars={muted} />
              </Panel>
            );
          })}
        </div>
      </div>

      <Panel
        title="Contas a pagar"
        action={<Badge accent="var(--clay)" variant="tint">{aPagar.length} {aPagar.length === 1 ? "aberta" : "abertas"}</Badge>}>
        {aPagar.length === 0
          ? <p style={{ fontFamily: "var(--font-body)", fontSize: 13, color: "var(--muted-2)", textAlign: "center", padding: "18px 0" }}>Tudo pago no período. Nada a vencer.</p>
          : (
            <ul style={{ listStyle: "none", margin: 0, padding: 0, border: "1px solid var(--hairline)", borderRadius: "var(--radius)", overflow: "hidden", background: "var(--surface)" }}>
              {aPagar.map((r) => (
                <LedgerRow key={r._u + r.id} name={escopoEff === "grupo" ? r.name + "  ·  " + r._u : r.name} value={r.value} paid={false} dueDate={r.venc ? window.dateLabel(r.venc) : null} category={r.fixa ? "Fixa" : (window.planoNome(r.plano) ? window.planoLabel(r.plano) : null)}
                  onToggle={() => requestPay(r)} onEdit={() => openEdit(r)} onDelete={() => delRow(r)} />
              ))}
            </ul>
          )}
        <p style={{ fontFamily: "var(--font-body)", fontSize: 11.5, color: "var(--muted-2)", lineHeight: 1.6, margin: "14px 2px 0" }}>
          Aperte “Pago” para baixar a conta (escolha a conta de saída e o dia) — avulsas saem do Painel; fixas saem da aba Despesas fixas. Inclui as despesas fixas pendentes do horizonte.
        </p>
      </Panel>

      {/* ---- Confirmar pagamento ---- */}
      <Dialog open={!!payDlg} title="Confirmar pagamento" onClose={() => setPayDlg(null)} width={460}
        footer={<><Button onClick={() => setPayDlg(null)}>Cancelar</Button><Button variant="solid" accent="var(--jade)" onClick={confirmPay}>Confirmar pagamento</Button></>}>
        {payDlg && (
          <div style={{ display: "grid", gap: 16 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "12px 14px", background: "var(--ink)", border: "1px solid var(--hairline)", borderRadius: "var(--radius-sm)" }}>
              <span style={{ fontFamily: "var(--font-body)", fontSize: 14, color: "var(--paper)", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{payDlg.row.name}{escopoEff === "grupo" ? "  ·  " + payDlg.row._u : ""}</span>
              <span style={{ fontFamily: "var(--font-display)", fontSize: 18, color: "var(--clay)", whiteSpace: "nowrap" }}>{window.BRL(payDlg.row.value)}</span>
            </div>
            <p style={{ fontFamily: "var(--font-body)", fontSize: 12.5, color: "var(--muted)", lineHeight: 1.6, margin: 0 }}>Selecione a conta de saída e confirme o dia do pagamento.</p>
            <Select label="Conta de saída" value={payDlg.conta} onChange={(v) => setPayDlg({ ...payDlg, conta: v })} options={D.contasOpcoes} accent="var(--jade)" />
            <Input label="Dia do pagamento" type="date" value={payDlg.data} onChange={(v) => setPayDlg({ ...payDlg, data: v })} icon="calendar-check" accent="var(--jade)" inputStyle={{ colorScheme: "dark" }} />
          </div>
        )}
      </Dialog>

      {/* ---- Editar lançamento ---- */}
      <Dialog open={!!editDlg} title="Editar lançamento" onClose={() => setEditDlg(null)} width={480}
        footer={<><Button onClick={() => setEditDlg(null)}>Cancelar</Button><Button variant="solid" onClick={saveEdit}>Salvar</Button></>}>
        {editDlg && (
          <div style={{ display: "grid", gap: 16 }}>
            {editDlg.row.fixa && <Badge accent="var(--brass)" variant="tint">Despesa fixa · edição vale só para {window.monthLabel((window.ddmmToISO(editDlg.row.venc) || window.todayISO()).slice(0, 7))}</Badge>}
            <Input label="Descrição" value={editDlg.descricao} onChange={(v) => setEditDlg({ ...editDlg, descricao: v })} icon="tag" placeholder="Fornecedor / despesa" />
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
              <Input label="Valor" prefix="R$" value={editDlg.valor} onChange={(v) => setEditDlg({ ...editDlg, valor: v })} placeholder="0,00" />
              <Input label="Vencimento" type="date" value={editDlg.venc} onChange={(v) => setEditDlg({ ...editDlg, venc: v })} icon="calendar" inputStyle={{ colorScheme: "dark" }} />
            </div>
          </div>
        )}
      </Dialog>
    </div>
  );
}

const navMiniFx = { width: 28, height: 28, borderRadius: "50%", background: "none", border: "none", display: "grid", placeItems: "center", cursor: "pointer", color: "var(--muted)" };

window.FluxoCaixa = FluxoCaixa;
