// Accounting view — Ingresos / Egresos + PDF uploads (stored in IndexedDB)
// Uses the global openIDB() / fileSave / fileGet / fileDelete helpers from store.jsx

async function pdfPut(id, blob) {
  // Bridge for old-style API used inside this view
  const db = await window.openIDB();
  return new Promise((res, rej) => {
    const rec = { id, name: blob.name || "documento.pdf", type: blob.type || "application/pdf",
                  size: blob.size, blob, savedAt: new Date().toISOString() };
    const tx = db.transaction("pdfs", "readwrite");
    tx.objectStore("pdfs").put(rec, id);
    tx.oncomplete = () => res();
    tx.onerror = () => rej(tx.error);
  });
}
async function pdfGet(id) {
  const rec = await window.fileGet(id);
  return rec ? rec.blob : null;
}
async function pdfDel(id) { return window.fileDelete(id); }

async function openPdfInTab(id) {
  return window.fileOpenInNewTab(id);
}

// ---------- Helpers ----------
function defaultAccounting() {
  return {
    entries: [], // each: { id, type: 'ingreso'|'egreso', kind: 'factura'|'boleta'|'cotizacion'|'otro', number, party, date, amount, status: 'pendiente'|'pagado'|'cobrado', pdfId?, quoteId?, notes }
  };
}

// ---------- Main view ----------
function AccountingView({ state, setState, totals }) {
  // Defensive: tolerate legacy shapes where accounting was stored as an array.
  const rawAcc = state.accounting;
  const acc = (rawAcc && !Array.isArray(rawAcc) && typeof rawAcc === "object")
    ? rawAcc
    : { entries: Array.isArray(rawAcc) ? rawAcc : [] };
  const entriesAll = Array.isArray(acc.entries) ? acc.entries : [];
  const setAcc = (patch) => setState(s => {
    const base = (s.accounting && !Array.isArray(s.accounting) && typeof s.accounting === "object")
      ? s.accounting
      : { entries: Array.isArray(s.accounting) ? s.accounting : [] };
    if (!Array.isArray(base.entries)) base.entries = [];
    return { ...s, accounting: { ...base, ...patch } };
  });

  const [tab, setTab] = React.useState("all"); // all | ingreso | egreso
  const [editing, setEditing] = React.useState(null);
  const [search, setSearch] = React.useState("");

  // Sync awarded quotes into "ingresos pendientes"
  React.useEffect(() => {
    const awarded = (state.quotes || []).filter(q => q.status === "aprobada");
    if (awarded.length === 0) return;
    const existing = new Set(entriesAll.map(e => e.quoteId).filter(Boolean));
    const toAdd = awarded.filter(q => !existing.has(q.id)).map(q => ({
      id: uid("acc"),
      type: "ingreso",
      kind: "cotizacion",
      number: q.id,
      party: q.client,
      date: q.date,
      amount: q.total,
      status: "pendiente",
      quoteId: q.id,
      notes: `Cotización adjudicada · ${q.project}`,
    }));
    if (toAdd.length) setAcc({ entries: [...toAdd, ...entriesAll] });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [state.quotes]);

  const entries = entriesAll.filter(e => {
    if (tab !== "all" && e.type !== tab) return false;
    if (!search.trim()) return true;
    const t = (e.number + " " + (e.party || "") + " " + (e.notes || "")).toLowerCase();
    return t.includes(search.toLowerCase());
  }).sort((a, b) => (b.date || "").localeCompare(a.date || ""));

  const sum = (type, status) => entriesAll
    .filter(e => e.type === type && (!status || e.status === status))
    .reduce((s, e) => s + (+e.amount || 0), 0);

  const totalIngresos = sum("ingreso");
  const totalEgresos = sum("egreso");
  const ingresosCobrados = sum("ingreso", "cobrado") + sum("ingreso", "pagado");
  const egresosPagados = sum("egreso", "pagado");
  const balance = ingresosCobrados - egresosPagados;
  const pendienteCobro = totalIngresos - ingresosCobrados;
  const pendientePago = totalEgresos - egresosPagados;

  const remove = (id, pdfId) => {
    if (!confirm("¿Eliminar este registro?")) return;
    setAcc({ entries: entriesAll.filter(e => e.id !== id) });
    if (pdfId) pdfDel(pdfId).catch(()=>{});
  };

  return (
    <>
      <Topbar
        title="Contabilidad"
        crumb="Ingresos · Egresos"
        actions={
          <>
            <button className="btn" onClick={() => setEditing({ type: "egreso", kind: "factura" })}>
              <Icon.plus /> Egreso
            </button>
            <button className="btn primary" onClick={() => setEditing({ type: "ingreso", kind: "factura" })}>
              <Icon.plus /> Ingreso
            </button>
          </>
        }
      />
      <div className="content narrow">
        <div className="kpi-grid">
          <div className="kpi accent">
            <div className="label">Balance neto</div>
            <div className="value">{clp(balance)}</div>
            <div className="delta">Cobrado − Pagado</div>
          </div>
          <div className="kpi">
            <div className="label">Ingresos cobrados</div>
            <div className="value">{clp(ingresosCobrados)}</div>
            <div className="delta">Pendiente: {clp(pendienteCobro)}</div>
          </div>
          <div className="kpi">
            <div className="label">Egresos pagados</div>
            <div className="value">{clp(egresosPagados)}</div>
            <div className="delta down">Pendiente: {clp(pendientePago)}</div>
          </div>
          <div className="kpi">
            <div className="label">Movimientos totales</div>
            <div className="value num">{entriesAll.length}</div>
            <div className="delta">{entriesAll.filter(e=>e.pdfId).length} con PDF</div>
          </div>
        </div>

        <div className="card">
          <div className="card-head">
            <div className="row" style={{flex:1,gap:10,alignItems:"center",flexWrap:"wrap"}}>
              <div className="row" style={{gap:4}}>
                {[
                  ["all", "Todos"],
                  ["ingreso", "Ingresos"],
                  ["egreso", "Egresos"],
                ].map(([k, l]) => (
                  <button key={k} className={`btn sm ${tab === k ? "primary" : ""}`}
                          onClick={() => setTab(k)}>{l}</button>
                ))}
              </div>
              <div className="row" style={{flex:1,maxWidth:340,gap:8,padding:"6px 10px",border:"1px solid var(--line-strong)",borderRadius:8}}>
                <Icon.search size={16} />
                <input value={search} onChange={e => setSearch(e.target.value)}
                       placeholder="Buscar por N° de documento, cliente, nota…"
                       style={{border:0,background:"transparent",flex:1,outline:"none"}} />
              </div>
              <span className="muted" style={{fontSize:12}}>{entries.length} de {entriesAll.length}</span>
            </div>
          </div>
          <div className="card-body flush" style={{overflow:"auto",maxHeight:"calc(100vh - 360px)"}}>
            <table className="data">
              <thead>
                <tr>
                  <th style={{width:90}}>Tipo</th>
                  <th style={{width:90}}>Doc.</th>
                  <th style={{width:120}}>Número</th>
                  <th>Cliente / proveedor</th>
                  <th style={{width:100}}>Fecha</th>
                  <th style={{width:140}} className="num">Monto</th>
                  <th style={{width:110}}>Estado</th>
                  <th style={{width:80}}>PDF</th>
                  <th style={{width:80}}></th>
                </tr>
              </thead>
              <tbody>
                {entries.length === 0 ? (
                  <tr><td colSpan={9}>
                    <div className="empty">
                      <div className="ico">∅</div>
                      Sin registros — agrega un ingreso o egreso para comenzar.
                    </div>
                  </td></tr>
                ) : entries.map(e => (
                  <tr key={e.id} onClick={() => setEditing(e)} style={{cursor:"pointer"}}>
                    <td>
                      <span className={`badge ${e.type === "ingreso" ? "ok" : ""}`} style={{
                        background: e.type === "ingreso" ? "#e6f4ea" : "#fdecea",
                        color: e.type === "ingreso" ? "var(--ok)" : "var(--danger)",
                        borderColor: e.type === "ingreso" ? "#bddfc4" : "#f5c6c3",
                      }}>
                        {e.type === "ingreso" ? "Ingreso" : "Egreso"}
                      </span>
                    </td>
                    <td style={{textTransform:"capitalize",fontSize:12,color:"var(--ink-2)"}}>{e.kind}</td>
                    <td className="mono">{e.number}</td>
                    <td style={{fontWeight:600}}>
                      {e.party || "—"}
                      {e.notes && <div className="muted" style={{fontSize:11,fontWeight:400,marginTop:2}}>{e.notes}</div>}
                    </td>
                    <td className="muted">{e.date}</td>
                    <td className="num" style={{fontWeight:700,color: e.type === "ingreso" ? "var(--ok)" : "var(--danger)"}}>
                      {e.type === "ingreso" ? "+" : "−"} {clp(e.amount)}
                    </td>
                    <td>
                      <span className={`badge ${e.status === "pagado" || e.status === "cobrado" ? "ok" : ""}`}>
                        {e.status}
                      </span>
                    </td>
                    <td>
                      {e.pdfId ? (
                        <button className="btn sm" onClick={(ev) => { ev.stopPropagation(); openPdfInTab(e.pdfId); }} title="Abrir PDF">
                          📄 Ver
                        </button>
                      ) : <span className="muted" style={{fontSize:11}}>—</span>}
                    </td>
                    <td onClick={e => e.stopPropagation()}>
                      <button className="btn danger icon" title="Eliminar"
                              onClick={() => remove(e.id, e.pdfId)}>
                        <Icon.trash />
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="muted" style={{fontSize:12, marginTop:12, lineHeight:1.6}}>
          💡 Las cotizaciones marcadas como <b>"aprobada"</b> aparecen automáticamente aquí como ingresos pendientes de cobro.
          Los PDF se guardan localmente en este dispositivo (IndexedDB). Para mantenerlos entre dispositivos, descarga un respaldo desde la pestaña <b>Respaldo</b>.
        </div>
      </div>

      {editing && (
        <AccountingEntryModal
          initial={editing}
          onClose={() => setEditing(null)}
          onSave={(data, file) => {
            (async () => {
              let pdfId = data.pdfId;
              if (file) {
                pdfId = pdfId || uid("pdf");
                await pdfPut(pdfId, file);
              }
              const entry = { ...data, pdfId };
              if (entry.id) {
                setAcc({ entries: entriesAll.map(e => e.id === entry.id ? entry : e) });
              } else {
                entry.id = uid("acc");
                setAcc({ entries: [entry, ...entriesAll] });
              }
              setEditing(null);
            })();
          }}
        />
      )}
    </>
  );
}

function AccountingEntryModal({ initial, onClose, onSave }) {
  const today = new Date().toISOString().slice(0, 10);
  const [e, setE] = React.useState({
    id: initial.id || null,
    type: initial.type || "ingreso",
    kind: initial.kind || "factura",
    number: initial.number || "",
    party: initial.party || "",
    date: initial.date || today,
    amount: initial.amount || 0,
    status: initial.status || (initial.type === "ingreso" ? "pendiente" : "pendiente"),
    pdfId: initial.pdfId || null,
    quoteId: initial.quoteId || null,
    notes: initial.notes || "",
  });
  const [file, setFile] = React.useState(null);
  const fileRef = React.useRef(null);
  const set = (patch) => setE(s => ({ ...s, ...patch }));
  const valid = e.number.trim() && e.party.trim() && +e.amount > 0;

  function submit(ev) {
    ev.preventDefault();
    if (!valid) return;
    onSave({ ...e, amount: +e.amount }, file);
  }

  const statusOpts = e.type === "ingreso"
    ? [["pendiente", "Pendiente de cobro"], ["cobrado", "Cobrado"]]
    : [["pendiente", "Pendiente de pago"], ["pagado", "Pagado"]];

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={ev => ev.stopPropagation()} style={{maxWidth:640}}>
        <div className="modal-head">
          <h2>{e.id ? "Editar movimiento" : "Nuevo movimiento contable"}</h2>
          <button className="btn ghost" onClick={onClose}>✕</button>
        </div>
        <form onSubmit={submit}>
          <div className="modal-body stack" style={{gap:14}}>
            <div className="grid-2">
              <div className="field">
                <label>Tipo</label>
                <select value={e.type} onChange={ev => set({ type: ev.target.value })}
                        disabled={!!e.quoteId}>
                  <option value="ingreso">Ingreso (lo que recibo)</option>
                  <option value="egreso">Egreso (lo que pago)</option>
                </select>
              </div>
              <div className="field">
                <label>Documento</label>
                <select value={e.kind} onChange={ev => set({ kind: ev.target.value })}>
                  <option value="factura">Factura</option>
                  <option value="boleta">Boleta</option>
                  <option value="cotizacion">Cotización adjudicada</option>
                  <option value="otro">Otro / movimiento manual</option>
                </select>
              </div>
            </div>
            <div className="grid-2">
              <div className="field">
                <label>N° documento <span style={{color:"var(--danger)"}}>*</span></label>
                <input value={e.number} onChange={ev => set({ number: ev.target.value })}
                       placeholder="Ej. 12345 / COT-2026-0001" autoFocus required />
              </div>
              <div className="field">
                <label>{e.type === "ingreso" ? "Cliente" : "Proveedor"} <span style={{color:"var(--danger)"}}>*</span></label>
                <input value={e.party} onChange={ev => set({ party: ev.target.value })} required />
              </div>
            </div>
            <div className="grid-3">
              <div className="field">
                <label>Fecha</label>
                <input type="date" value={e.date} onChange={ev => set({ date: ev.target.value })} />
              </div>
              <div className="field">
                <label>Monto neto (CLP) <span style={{color:"var(--danger)"}}>*</span></label>
                <input type="number" min="0" value={e.amount}
                       onChange={ev => set({ amount: ev.target.value })} required />
              </div>
              <div className="field">
                <label>Estado</label>
                <select value={e.status} onChange={ev => set({ status: ev.target.value })}>
                  {statusOpts.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                </select>
              </div>
            </div>
            <div className="field">
              <label>Notas / glosa</label>
              <textarea value={e.notes} onChange={ev => set({ notes: ev.target.value })}
                        placeholder="Detalle, OC, glosa…" rows={2} />
            </div>

            <div style={{borderTop:"1px solid var(--line)",paddingTop:14}}>
              <label style={{fontSize:11,fontWeight:600,color:"var(--muted)",textTransform:"uppercase",letterSpacing:".08em"}}>Documento PDF (opcional)</label>
              <input ref={fileRef} type="file" accept="application/pdf,.pdf"
                     style={{display:"none"}}
                     onChange={ev => setFile(ev.target.files?.[0] || null)} />
              <div className="row" style={{gap:10,marginTop:8,alignItems:"center"}}>
                <button type="button" className="btn" onClick={() => fileRef.current?.click()}>
                  <Icon.upload /> {file ? "Cambiar archivo" : (e.pdfId ? "Reemplazar PDF" : "Subir PDF")}
                </button>
                {file ? (
                  <span className="muted" style={{fontSize:13}}>📄 {file.name} ({Math.round(file.size / 1024)} KB)</span>
                ) : e.pdfId ? (
                  <>
                    <button type="button" className="btn sm" onClick={() => openPdfInTab(e.pdfId)}>
                      Ver PDF guardado
                    </button>
                    <button type="button" className="btn sm danger"
                            onClick={() => { pdfDel(e.pdfId); set({ pdfId: null }); }}>
                      Quitar PDF
                    </button>
                  </>
                ) : (
                  <span className="muted" style={{fontSize:12}}>Sin documento adjunto</span>
                )}
              </div>
            </div>
          </div>
          <div className="modal-foot row" style={{justifyContent:"flex-end",padding:"12px 18px",borderTop:"1px solid var(--line)"}}>
            <button type="button" className="btn" onClick={onClose}>Cancelar</button>
            <button type="submit" className="btn primary" disabled={!valid}>
              <Icon.check /> Guardar movimiento
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}

Object.assign(window, { AccountingView, AccountingEntryModal, pdfPut, pdfGet, pdfDel, openPdfInTab });
