// Checklist mensal — substitui a tabela de Lançamentos.
// Contas fixas recorrem automaticamente; o usuário só marca pago e ajusta valores.

const { useState: useStateC, useMemo: useMemoC, useRef: useRefC, useEffect: useEffectC } = React;

// Inline-editable money value
function MoneyCell({ value, onChange, className }) {
  const [editing, setEditing] = useStateC(false);
  const [draft, setDraft] = useStateC("");
  const ref = useRefC(null);
  useEffectC(() => { if (editing && ref.current) { ref.current.focus(); ref.current.select(); } }, [editing]);

  function commit() {
    setEditing(false);
    const n = window.parseValor(draft);
    if (!isNaN(n) && n >= 0 && Math.abs(n - value) > 0.001) onChange(n);
  }
  if (editing) {
    return (
      <input
        ref={ref}
        className="ck-money-input"
        value={draft}
        onChange={e => setDraft(e.target.value)}
        onBlur={commit}
        onKeyDown={e => { if (e.key === "Enter") commit(); if (e.key === "Escape") setEditing(false); }}
      />
    );
  }
  return (
    <button
      className={`ck-money ${className || ""}`}
      title="Clique para editar o valor"
      onClick={() => { setDraft(String(value).replace(".", ",")); setEditing(true); }}>
      {window.fmtBRLString(value)}
    </button>
  );
}

// One checklist row
const CK_REDUTIVEL_CLASSES = ["variavel"];
function CkRow({ t, isGasto, onToggle, onUpdate, onDelete }) {
  const pago = t.status === "Pago";
  const classe = window.classeForTx(t);
  const cdef = window.CLASSES.find(c => c.id === classe) || window.CLASSES[0];
  const [openCl, setOpenCl] = useStateC(false);
  const [menuPos, setMenuPos] = useStateC(null);
  const wrapRef = useRefC(null);
  const btnRef = useRefC(null);
  useEffectC(() => {
    if (!openCl) return;
    const place = () => {
      const r = btnRef.current?.getBoundingClientRect();
      if (!r) return;
      const H = 215, W = 170;
      const pageTop = r.bottom + window.scrollY + 5;
      const docH = document.documentElement.scrollHeight;
      const top = (pageTop + H > docH - 8) ? Math.max(8, r.top + window.scrollY - H - 5) : pageTop;
      const left = Math.max(8, Math.min(r.right + window.scrollX - W, document.documentElement.scrollWidth - W - 8));
      setMenuPos({ left, top });
    };
    place();
    const onDoc = e => { if (wrapRef.current && !wrapRef.current.contains(e.target) && !e.target.closest(".ck-classe-menu")) setOpenCl(false); };
    document.addEventListener("mousedown", onDoc);
    window.addEventListener("scroll", place, true);    window.addEventListener("resize", place);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      window.removeEventListener("scroll", place, true);
      window.removeEventListener("resize", place);
    };
  }, [openCl]);
  function pick(id) {
    onUpdate(t.id, { classe: id, redutivel: CK_REDUTIVEL_CLASSES.includes(id) });
    setOpenCl(false);
  }
  return (
    <div className={`ck-row ${pago ? "is-pago" : ""}`}>
      <button
        className={`ck-check ${pago ? "on" : ""}`}
        onClick={() => onToggle(t.id, "status")}
        title={pago ? "Remover validação" : "Validar lançamento"}>
        {pago && (
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3.2"><path d="M20 6L9 17l-5-5"/></svg>
        )}
      </button>
      <div className="ck-info">
        <span className="ck-desc">{t.description}</span>
        <span className="ck-meta">{t.category}{t.account ? " · " + t.account : ""}{t.fixa ? " · 📍 fixa" : ""}</span>
      </div>
      {t.type === "Despesa" ? (
        <div className="ck-classe-wrap" ref={wrapRef}>
          <button
            ref={btnRef}
            className={`ck-classe-pill c-${classe} ${openCl ? "open" : ""}`}
            onClick={() => setOpenCl(o => !o)}
            title="Classe do gasto">
            {cdef.icon} {cdef.label}
            <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3"><path d="M6 9l6 6 6-6"/></svg>
          </button>
          {openCl && menuPos && ReactDOM.createPortal(
            <div className="ck-classe-menu" style={{ left: menuPos.left, top: menuPos.top }} onMouseDown={e => e.stopPropagation()}>
              {window.CLASSES.map(c => (
                <button key={c.id} className={c.id === classe ? "sel" : ""} onClick={() => pick(c.id)}>{c.icon} {c.label}</button>
              ))}
            </div>,
            document.body
          )}
        </div>
      ) : <span className="ck-redu-spacer"/>}
      <MoneyCell value={t.amount} onChange={v => onUpdate(t.id, { amount: v })} className={t.type === "Receita" ? "in" : ""}/>
      <button className="ck-del" onClick={() => onDelete(t.id)} title="Excluir">
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M3 6h18M8 6V4a1 1 0 011-1h6a1 1 0 011 1v2M19 6l-1 14a2 2 0 01-2 2H8a2 2 0 01-2-2L5 6"/></svg>
      </button>
    </div>
  );
}

// Quick-add row: description + value, Enter saves. No modal.
function CkQuickAdd({ bucket, categorias, contas, onAdd, year, month }) {
  const [open, setOpen] = useStateC(false);
  const [desc, setDesc] = useStateC("");
  const [val, setVal] = useStateC("");
  const gastoCats = categorias.filter(c => !["Receita","Caridade","Capital Ativo","Capital Passivo"].includes(c.tipo)).map(c => c.nome);
  const defaultCat = bucket === "receita" ? "💸 Receita"
    : bucket === "caridade" ? "🙏 Caridade"
    : bucket === "ativo" ? "🚀 Capital Ativo"
    : bucket === "passivo" ? "📈 Investimento"
    : (gastoCats[0] || "🤷 Outros");
  const [cat, setCat] = useStateC(defaultCat);

  function save() {
    const n = window.parseValor(val);
    if (!desc.trim() || isNaN(n) || n <= 0) return;
    const day = String(Math.min(new Date().getDate(), 28)).padStart(2, "0");
    onAdd({
      id: window.uid(),
      description: desc.trim(),
      date: `${year}-${String(month + 1).padStart(2, "0")}-${day}`,
      amount: n,
      account: contas[0] || "PIX",
      category: bucket === "gastos" ? cat : defaultCat,
      type: bucket === "receita" ? "Receita" : "Despesa",
      status: "Pendente",
      redutivel: false,
      fixa: false,
    });
    setDesc(""); setVal("");
  }

  if (!open) {
    return <button className="ck-add-btn" onClick={() => setOpen(true)}>+ Adicionar</button>;
  }
  return (
    <div className="ck-quick">
      <input
        className="ck-qi-desc" placeholder="Descrição" value={desc} autoFocus
        onChange={e => setDesc(e.target.value)}
        onKeyDown={e => { if (e.key === "Enter") save(); if (e.key === "Escape") setOpen(false); }}/>
      {bucket === "gastos" && (
        <select className="ck-qi-cat" value={cat} onChange={e => setCat(e.target.value)}>
          {gastoCats.map(c => <option key={c} value={c}>{c}</option>)}
        </select>
      )}
      <input
        className="ck-qi-val" placeholder="0,00" value={val} inputMode="decimal"
        onChange={e => setVal(e.target.value)}
        onKeyDown={e => { if (e.key === "Enter") save(); if (e.key === "Escape") setOpen(false); }}/>
      <button className="ck-qi-save" onClick={save} title="Salvar (Enter)">
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3"><path d="M20 6L9 17l-5-5"/></svg>
      </button>
      <button className="ck-qi-cancel" onClick={() => setOpen(false)} title="Fechar (Esc)">
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4"><path d="M18 6L6 18M6 6l12 12"/></svg>
      </button>
    </div>
  );
}

// Group of rows with subtotal vs. meta
function CkGroup({ id, icon, title, sub, txs, target, isGasto, onToggle, onUpdate, onDelete, quickAdd }) {
  const [fCl, setFCl] = useStateC(null);
  const [fCat, setFCat] = useStateC("");
  const total = txs.reduce((s, t) => s + Number(t.amount || 0), 0);
  const pagoCount = txs.filter(t => t.status === "Pago").length;
  const over = target != null && total > target + 0.5;
  const fill = target > 0 ? Math.min(total / target, 1) * 100 : 0;
  const clCounts = {};
  if (isGasto) for (const t of txs) { const c = window.classeForTx(t); clCounts[c] = (clCounts[c] || 0) + 1; }
  const cats = isGasto ? [...new Set(txs.map(t => t.category))].sort() : [];
  const shown = isGasto ? txs.filter(t => (!fCl || window.classeForTx(t) === fCl) && (!fCat || t.category === fCat)) : txs;
  const filtered = fCl || fCat;
  const shownTotal = shown.reduce((s, t) => s + Number(t.amount || 0), 0);
  return (
    <div className="card ck-group" data-screen-label={title}>
      <div className="ck-group-head">
        <div className="ckg-title">
          <span className="ckg-icon">{icon}</span>
          <div>
            <h3>{title}</h3>
            <span className="ckg-sub">{sub}</span>
          </div>
        </div>
        <div className="ckg-right">
          <span className="ckg-count">{pagoCount}/{txs.length} validados</span>
          <div className="ckg-total">
            <strong className={over ? "neg" : ""}>{window.fmtBRLString(total)}</strong>
            {target != null && <span className="ckg-target">de {window.fmtBRLString(target)}</span>}
          </div>
        </div>
      </div>
      {target != null && (
        <div className="ckg-bar"><div className={over ? "over" : ""} style={{width: fill + "%"}}/></div>
      )}
      {isGasto && txs.length > 0 && (
        <div className="ck-filter">
          <button className={`ckf-chip ${!fCl ? "on" : ""}`} onClick={() => setFCl(null)}>Todas</button>
          {window.CLASSES.filter(c => clCounts[c.id]).map(c => (
            <button key={c.id} className={`ckf-chip ${fCl === c.id ? "on" : ""}`} onClick={() => setFCl(fCl === c.id ? null : c.id)}>{c.icon} {c.label} ({clCounts[c.id]})</button>
          ))}
          <select className="ckf-cat" value={fCat} onChange={e => setFCat(e.target.value)}>
            <option value="">Todas as categorias</option>
            {cats.map(c => <option key={c}>{c}</option>)}
          </select>
          {filtered && <span className="ckf-sum">{shown.length} {shown.length === 1 ? "item" : "itens"} · <strong>{window.fmtBRLString(shownTotal)}</strong></span>}
        </div>
      )}
      <div className="ck-rows">
        {shown.map(t => (
          <CkRow key={t.id} t={t} isGasto={isGasto} onToggle={onToggle} onUpdate={onUpdate} onDelete={onDelete}/>
        ))}
        {txs.length === 0 && <div className="ck-empty-group">Nada lançado ainda.</div>}
        {txs.length > 0 && shown.length === 0 && <div className="ck-empty-group">Nada com esse filtro.</div>}
      </div>
      {quickAdd}
    </div>
  );
}

// ---------- LANÇAMENTOS = CHECKLIST DO MÊS ----------
function LancamentosPage({ txs, month, year, onChangeMonth, plano, categorias, contas, onToggle, onUpdate, onDelete, onAdd, onCopyPrev, canCopyPrev, segurosFaltando, onAddSeguros, confronto, onConfronto, fechados, onFecharMes }) {
  const monthTxs = useMemoC(() => window.txByMonth(txs, year, month), [txs, year, month]);
  const receitas = monthTxs.filter(t => t.type === "Receita");
  const despesas = monthTxs.filter(t => t.type === "Despesa");
  const byBucket = k => despesas.filter(t => window.bucketForCategory(t.category) === k);

  const g = plano.gastos;
  // Projection: if everything pending gets paid, where do gastos land vs the 70% ceiling?
  const projected = g.used; // used already includes pending (lançado = comprometido)
  const pagoSoFar = g.gastosPago;
  // Barra de status: escala 0 → max(gasto total, receita); segmentada por classe de gasto
  const pctR = plano.income > 0 ? (projected / plano.income) * 100 : 0;
  const gastosCls = window.byClasse(despesas.filter(t => window.bucketForCategory(t.category) === "gastos"));
  const scaleMax = Math.max(projected, plano.income) || 1;
  const metaPct = (plano.income * 0.70 / scaleMax) * 100;
  const recPct = (plano.income / scaleMax) * 100;

  const buckets = [
    { key: "receita", icon: "💸", title: "Receitas", sub: "entradas do mês", txs: receitas, target: null },
    { key: "gastos", icon: "🏠", title: "Gastos", sub: "teto de 70% da receita", txs: byBucket("gastos"), target: plano.income * 0.70, isGasto: true },
    { key: "caridade", icon: "🙏", title: "Caridade", sub: "10% da receita", txs: byBucket("caridade"), target: plano.income * 0.10 },
    { key: "ativo", icon: "🚀", title: "Capital Ativo", sub: "10% · projetos pessoais", txs: byBucket("ativo"), target: plano.income * 0.10 },
    { key: "passivo", icon: "📈", title: "Capital Passivo", sub: "10% · investimentos", txs: byBucket("passivo"), target: plano.income * 0.10 },
  ];

  return (
    <div className="page" data-screen-label="Checklist do mês">
      <div className="page-head">
        <div>
          <h2>✔️ Checklist de {window.MESES_FULL[month]}</h2>
          <span className="page-hint">Valide cada lançamento (✓), ajuste valores clicando neles e feche o balanço do mês no final da página.</span>
        </div>
      </div>

      {/* Projeção dos 70% */}
      {plano.income > 0 && (
        <div className={`card ck-proj ${g.over ? "proj-over" : "proj-ok"}`}>
          <div className="ck-proj-top">
            <div className="ckp-msg">
              {g.over ? (
                <span>🚨 Com tudo lançado, seus gastos fecham <b>{window.fmtBRLString(g.overBy)} acima</b> do teto de 70%. Corte nos <b>✂️ redutíveis ainda não validados</b>: {window.fmtBRLString(g.redutivelPendente)} disponíveis.</span>
              ) : (
                <span>✅ Com tudo que está lançado, o mês fecha <b>{window.fmtBRLString(g.target - projected)} abaixo</b> do teto de 70%.</span>
              )}
            </div>
            <div className="ckp-nums">
              <span><i className="dotmark paid"/>Validado {window.fmtBRLString(pagoSoFar)}</span>
              <span><i className="dotmark pend"/>Lançado {window.fmtBRLString(projected)}</span>
              <span className="ckp-teto">Meta ≤ 70% · {window.fmtBRLString(g.target)}</span>
            </div>
          </div>
          <div className="ckp-status-wrap">
            <div className="res-bar ckp-status">
              {gastosCls.map(c => (
                <div key={c.id} className={`ckp-seg ${c.id === "variavel" ? "seg-redutivel" : ""}`} title={`${c.icon} ${c.label}: ${window.fmtBRLString(c.value)}`} style={{width: (c.value / scaleMax) * 100 + "%", background: c.color}}></div>
              ))}
              <span className="res-tick" style={{left: metaPct + "%"}}></span>
              {recPct < 99.5 && <span className="res-tick" style={{left: recPct + "%"}}></span>}
            </div>
            <div className="ckp-meta-tick" style={{left: metaPct + "%"}}><span>meta 70%</span></div>
            <div className="ckp-meta-tick tick-rec" style={{left: recPct + "%"}}><span>receita</span></div>
          </div>
          <div className="ckp-scale">
            <span>Gastos <strong>{window.fmtBRLString(projected)}</strong> · {Math.round(pctR)}% da receita</span>
            <span className="ckp-receita">Receita {window.fmtBRLString(plano.income)}</span>
          </div>
          <div className="ckp-cls-legend">
            {gastosCls.map(c => (
              <span key={c.id} className={c.id === "variavel" ? "leg-redutivel" : ""}><i style={{background: c.color}}></i>{c.icon} {c.label} <strong>{window.fmtBRLString(c.value)}</strong></span>
            ))}
          </div>
        </div>
      )}

      <window.ConfrontoCard
        despesas={despesas}
        monthKey={`${year}-${String(month + 1).padStart(2, "0")}`}
        monthLabel={window.MESES_FULL[month]}
        confronto={confronto || {}}
        onConfronto={onConfronto}
        onDelete={onDelete}
      />

      {monthTxs.length === 0 && canCopyPrev && (
        <div className="card ck-seed">
          <span>Este mês ainda está vazio.</span>
          <button className="btn-green" onClick={onCopyPrev}>Trazer contas fixas do mês anterior</button>
        </div>
      )}

      {buckets.map(b => (
        <CkGroup
          key={b.key}
          icon={b.icon} title={b.title} sub={b.sub}
          txs={b.txs}
          target={plano.income > 0 ? b.target : null}
          isGasto={b.isGasto}
          onToggle={onToggle} onUpdate={onUpdate} onDelete={onDelete}
          quickAdd={<CkQuickAdd bucket={b.key} categorias={categorias} contas={contas} onAdd={onAdd} year={year} month={month}/>}
        />
      ))}

      <FechamentoMesCard
        monthTxs={monthTxs} receitas={receitas} despesas={despesas}
        monthLabel={window.MESES_FULL[month] + "/" + year}
        mKey={`${year}-${String(month + 1).padStart(2, "0")}`}
        fechados={fechados || {}} onFecharMes={onFecharMes} plano={plano}
      />
    </div>
  );
}

// ---------- FECHAMENTO DO MÊS ----------
// O usuário valida cada lançamento e então fecha o balanço do mês.
// Receitas e despesas lançadas são obrigatórias para fechar.
function FechamentoMesCard({ monthTxs, receitas, despesas, monthLabel, mKey, fechados, onFecharMes, plano }) {
  const fmt = window.fmtBRLString;
  const fechado = fechados[mKey];
  const total = monthTxs.length;
  const validados = monthTxs.filter(t => t.status === "Pago").length;
  const temReceita = receitas.length > 0;
  const temDespesa = despesas.length > 0;
  const tudoValidado = total > 0 && validados === total;
  const pronto = temReceita && temDespesa && tudoValidado;
  const receita = receitas.reduce((s, t) => s + Number(t.amount || 0), 0);
  const despesa = despesas.reduce((s, t) => s + Number(t.amount || 0), 0);
  const saldo = receita - despesa;
  const metaOk = plano.income > 0 && !plano.gastos.over;

  if (fechado) {
    return (
      <div className="card ck-fech is-fechado" data-screen-label="Fechamento do mês">
        <div className="ckf-head">
          <h3>🔒 {monthLabel} fechado</h3>
          <span className="ckf-data">em {new Date(fechado.em).toLocaleDateString("pt-BR")}</span>
        </div>
        <div className="ckf-nums">
          <span>Receitas <strong className="in">{fmt(fechado.receita)}</strong></span>
          <span>Despesas <strong className="out">{fmt(fechado.despesa)}</strong></span>
          <span>Saldo <strong className={fechado.saldo >= 0 ? "in" : "out"}>{fmt(fechado.saldo)}</strong></span>
          {fechado.metaOk != null && (fechado.metaOk
            ? <span className="an-flag good">✅ Meta 70% cumprida</span>
            : <span className="an-flag bad">🚨 Acima da meta de 70%</span>)}
        </div>
        <button className="btn-ghost sm" onClick={() => onFecharMes(mKey, null)}>Reabrir mês</button>
      </div>
    );
  }

  const reqs = [
    { ok: temReceita, label: "Receitas do mês lançadas" },
    { ok: temDespesa, label: "Despesas do mês lançadas" },
    { ok: tudoValidado, label: `Lançamentos validados (${validados}/${total})` },
  ];
  return (
    <div className="card ck-fech" data-screen-label="Fechamento do mês">
      <div className="ckf-head">
        <h3>🏁 Fechamento de {monthLabel}</h3>
        <span className="page-hint">Valide cada lançamento e feche o balanço do mês.</span>
      </div>
      <div className="ckf-reqs">
        {reqs.map((r, i) => (
          <span key={i} className={`ckf-req ${r.ok ? "ok" : ""}`}>{r.ok ? "✅" : "○"} {r.label}</span>
        ))}
      </div>
      {total > 0 && (
        <div className="ckf-bar"><div style={{width: (validados / total) * 100 + "%"}}></div></div>
      )}
      <div className="ckf-foot">
        <span className="ckf-preview">Balanço: <strong className="in">{fmt(receita)}</strong> − <strong className="out">{fmt(despesa)}</strong> = <strong className={saldo >= 0 ? "in" : "out"}>{fmt(saldo)}</strong></span>
        <button className="btn-green" disabled={!pronto}
          title={pronto ? "Fechar o balanço do mês" : "Lance receitas e despesas e valide tudo para fechar"}
          onClick={() => onFecharMes(mKey, { em: new Date().toISOString(), receita, despesa, saldo, metaOk })}>
          Fechar o mês
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { LancamentosPage });
