/* Kay Construction — Document generators (part 2): Invoice + Kwitansi (Receipt). */

const PAY_METHODS = ["transfer", "tunai", "cek", "giro"];

/* ===================================================================
   INVOICE
   =================================================================== */
function InvoiceList() {
  useStore();
  const [lang] = useLang();
  const [q, setQ] = useState(""); const [filter, setFilter] = useState("all");
  const [confirm, confirmNode] = useConfirm();
  let rows = S.all("invoices").slice().sort((a, b) => (b.issueDate || "").localeCompare(a.issueDate || ""));
  rows = rows.map((r) => ({ ...r, _status: S.invoiceStatus(r) }));
  if (filter !== "all") rows = rows.filter((r) => r._status === filter);
  if (q) rows = rows.filter((r) => (r.number + r.terminDesc + S.projectName(r.projectId)).toLowerCase().includes(q.toLowerCase()));
  return (
    <div>
      <PageHead title={t("doc.invoice")} sub={lang === "en" ? "Invoices per payment term." : "Invoice per termin pembayaran."}>
        <Button variant="primary" icon="plus" onClick={() => go("#/dokumen/invoice/baru")}>{t("common.new")} {t("doc.invoice")}</Button>
      </PageHead>
      <div className="toolbar">
        <div className="search"><Icon name="search" className="ico" /><Input value={q} onChange={(e) => setQ(e.target.value)} placeholder={t("common.search")} /></div>
        <div className="filters"><span className={"chip" + (filter === "all" ? " on" : "")} onClick={() => setFilter("all")}>{t("common.all")}</span>
          {["terkirim", "lunas sebagian", "lunas", "jatuh tempo", "draft"].map((s) => <span key={s} className={"chip" + (filter === s ? " on" : "")} onClick={() => setFilter(s)}>{tStatus(s)}</span>)}</div>
      </div>
      <div className="card"><div className="table-wrap"><table className="tbl">
        <thead><tr><th>{t("common.number")}</th><th>{t("common.project")}</th><th>{t("doc.terminDesc")}</th><th className="num">{t("common.total")}</th><th className="num">{t("col.outstanding")}</th><th>{t("col.due")}</th><th>{t("common.status")}</th><th></th></tr></thead>
        <tbody>
          {rows.length === 0 && <tr><td colSpan="8"><Empty icon="invoice" title={t("common.empty")} /></td></tr>}
          {rows.map((r) => { const tot = S.docTotals(r).total, paid = S.invoicePaid(r.id), sisa = tot - paid;
            const overdue = r.dueDate && S.daysBetween(r.dueDate, S.todayISO()) > 0 && sisa > 0;
            return (
            <tr key={r.id} className="clickable" onClick={() => go("#/dokumen/invoice/" + r.id)}>
              <td data-label={t("common.number")} className="mono" style={{ fontWeight: 600, fontSize: 12 }}>{r.number}</td>
              <td data-label={t("common.project")}>{S.projectName(r.projectId)}</td><td data-label={t("doc.terminDesc")}>{r.terminDesc}</td>
              <td data-label={t("common.total")} className="num">{S.formatRupiah(tot)}</td>
              <td data-label={t("col.outstanding")} className="num" style={{ fontWeight: sisa > 0 ? 600 : 400, color: sisa > 0 ? "var(--ink)" : "var(--muted)" }}>{sisa > 0 ? S.formatRupiah(sisa) : "—"}</td>
              <td data-label={t("col.due")} style={{ color: overdue ? "var(--neg)" : "inherit" }}>{S.shortDate(r.dueDate)}</td>
              <td data-label={t("common.status")}><StatusBadge status={r._status} /></td>
              <td className="num" onClick={(e) => e.stopPropagation()}><Button variant="ghost" size="sm" icon="trash" onClick={() => confirm(t("common.confirmDelete"), () => S.remove("invoices", r.id))} /></td>
            </tr>
          ); })}
        </tbody>
      </table></div></div>
      {confirmNode}
    </div>
  );
}

function InvoiceEditor({ id, createNew }) {
  useStore();
  const [lang] = useLang();
  const qp = routeQuery(window.location.hash);
  const existing = id ? S.find("invoices", id) : null;
  const [doc, setDoc] = useState(existing || {
    number: "", projectId: qp.project || "", terminNo: 1, terminDesc: "", issueDate: S.todayISO(), dueDate: S.addDays(S.todayISO(), 7),
    flatAmount: 0, discount: 0, ppnPercent: S.getDB().company.defaultPpn || 11, status: "draft", language: lang, note: ""
  });
  const [showPay, setShowPay] = useState(false);
  const [confirm, confirmNode] = useConfirm();
  if (id && !existing) return <Empty icon="invoice" title={t("common.empty")} action={<Button onClick={() => go("#/dokumen/invoice")}>{t("common.back")}</Button>} />;
  const set = (patch) => setDoc((o) => ({ ...o, ...patch }));
  const tot = S.docTotals(doc).total;
  const paid = id ? S.invoicePaid(id) : 0;
  const sisa = tot - paid;
  const payments = id ? S.all("payments").filter((p) => p.invoiceId === id) : [];
  const save = () => { const s = saveDoc("invoices", "invoice", doc); setDoc(s); if (createNew) go("#/dokumen/invoice/" + s.id); };
  const liveStatus = existing ? S.invoiceStatus({ ...doc, id }) : doc.status;

  return (
    <div>
      <EditorHead backPath="#/dokumen/invoice" backLabel={t("doc.invoice")} code={doc.number || t("common.new")} title={t("doc.invoice") + (doc.terminDesc ? " · " + doc.terminDesc : "")}
        statusNode={<StatusBadge status={liveStatus} />}
        actions={<>
          {!createNew && doc.number && sisa > 0 && <Button icon="kwitansi" onClick={() => setShowPay(true)}>{t("doc.recordPayment")}</Button>}
          {!createNew && doc.number && <Button icon="copy" onClick={() => { const c = S.duplicateDoc("invoices", "invoice", doc.id); if (c) go("#/dokumen/invoice/" + c.id); }}>{t("common.duplicate")}</Button>}
          {!createNew && doc.number && <Button icon="print" onClick={() => { save(); go("#/cetak/invoice/" + doc.id); }}>{t("common.print")}</Button>}
          <Button variant="primary" icon="check" onClick={save}>{t("common.save")}</Button>
        </>} />

      <div className="card pad" style={{ marginBottom: 20 }}>
        <div className="form-grid">
          <Field label={t("common.project")}><ProjectSelect value={doc.projectId} onChange={(v) => set({ projectId: v })} /></Field>
          <Field label={t("common.documentLang")}><DocLangToggle value={doc.language} onChange={(v) => set({ language: v })} /></Field>
          <Field label={t("doc.termin")}><Input type="number" min="1" value={doc.terminNo} onChange={(e) => set({ terminNo: parseInt(e.target.value, 10) || 1 })} /></Field>
          <Field label={t("doc.terminDesc")}><Input value={doc.terminDesc} onChange={(e) => set({ terminDesc: e.target.value })} placeholder={lang === "en" ? "e.g. Down Payment 30%" : "mis. Uang Muka 30%"} /></Field>
          <Field label={t("doc.issueDate")}><Input type="date" value={doc.issueDate} onChange={(e) => set({ issueDate: e.target.value })} /></Field>
          <Field label={t("doc.dueDate")}><Input type="date" value={doc.dueDate} onChange={(e) => set({ dueDate: e.target.value })} /></Field>
          <Field label={t("common.status")}><StatusSelect value={doc.status} onChange={(v) => set({ status: v })} options={INV_STATUSES} /></Field>
          <Field label={t("common.note")} optional><Input value={doc.note} onChange={(e) => set({ note: e.target.value })} /></Field>
        </div>
      </div>

      <div className="grid-2" style={{ alignItems: "start" }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
          <div className="card pad">
            <h2 className="section">{t("common.amount")}</h2>
            <Field label={t("doc.terminDesc") + " — " + t("common.amount")}><MoneyInput value={doc.flatAmount} onChange={(v) => set({ flatAmount: v })} /></Field>
            <div className="form-grid">
              <Field label={t("common.discount")} optional><MoneyInput value={doc.discount || 0} onChange={(v) => set({ discount: v })} /></Field>
              <Field label={t("common.ppn") + " (%)"}><Input className="num" value={doc.ppnPercent} onChange={(e) => set({ ppnPercent: parseFloat(e.target.value) || 0 })} /></Field>
            </div>
          </div>

          {!createNew && doc.number && (
            <div className="card">
              <div className="card-head"><h2 className="section" style={{ margin: 0 }}>{t("nav.kwitansi")}</h2>
                {sisa > 0 && <Button size="sm" icon="plus" onClick={() => setShowPay(true)}>{t("doc.recordPayment")}</Button>}</div>
              <div className="card-body" style={{ paddingTop: 8 }}>
                {payments.length === 0 ? <div className="muted tiny" style={{ padding: "6px 0" }}>{t("common.empty")}</div> :
                  payments.map((p) => (
                    <div key={p.id} className="row between" style={{ padding: "9px 0", borderBottom: "1px solid var(--line-soft)", cursor: "pointer" }} onClick={() => go("#/dokumen/kwitansi/" + p.id)}>
                      <div className="row" style={{ gap: 10 }}><span className="mono tiny" style={{ fontWeight: 600 }}>{p.number}</span><span className="subtle">{S.shortDate(p.date)}</span></div>
                      <span className="tnum" style={{ fontWeight: 600 }}>{S.formatRupiah(p.amount)}</span>
                    </div>
                  ))}
              </div>
            </div>
          )}
        </div>

        <div className="card pad">
          <div className="stat-line"><span>{t("common.subtotal")}</span><span className="v">{S.formatRupiah(S.docTotals(doc).subtotal)}</span></div>
          {doc.discount > 0 && <div className="stat-line"><span>{t("common.discount")}</span><span className="v">−{S.formatRupiah(doc.discount)}</span></div>}
          <div className="stat-line"><span>{t("common.ppn")} {S.docTotals(doc).ppnPercent}%</span><span className="v">{S.formatRupiah(S.docTotals(doc).ppnAmount)}</span></div>
          <div className="divider" style={{ margin: "12px 0" }}></div>
          <div className="stat-line" style={{ fontWeight: 600 }}><span className="serif" style={{ fontSize: 17 }}>{t("common.total")}</span><span className="v serif" style={{ fontSize: 19 }}>{S.formatRupiah(tot)}</span></div>
          {!createNew && doc.number && <>
            <div className="divider" style={{ margin: "12px 0" }}></div>
            <div className="stat-line"><span>{t("col.paid")}</span><span className="v" style={{ color: "var(--pos)" }}>{S.formatRupiah(paid)}</span></div>
            <div className="stat-line"><span style={{ fontWeight: 600 }}>{t("col.outstanding")}</span><span className="v" style={{ color: sisa > 0 ? "var(--neg)" : "var(--pos)" }}>{S.formatRupiah(sisa)}</span></div>
          </>}
        </div>
      </div>

      {showPay && <RecordPaymentModal invoice={{ ...doc, id }} sisa={sisa} onClose={() => setShowPay(false)} />}
      {confirmNode}
    </div>
  );
}

function RecordPaymentModal({ invoice, sisa, onClose }) {
  const [lang] = useLang();
  const project = S.find("projects", invoice.projectId);
  const client = project ? S.find("clients", project.clientId) : null;
  const [f, setF] = useState({
    date: S.todayISO(), amount: sisa > 0 ? sisa : 0, method: "transfer", bank: S.getDB().company.bankName || "",
    receivedFrom: client ? client.name : "",
    forPayment: (invoice.terminDesc || "") + " — " + (project ? project.name : "") + " (" + invoice.number + ")",
    language: invoice.language || lang, note: ""
  });
  const set = (k, v) => setF((o) => ({ ...o, [k]: v }));
  const save = () => {
    if (!f.amount) return alert(lang === "en" ? "Amount is required" : "Jumlah wajib diisi");
    saveDoc("payments", "payment", { ...f, invoiceId: invoice.id, projectId: invoice.projectId });
    // recompute invoice status
    const inv = S.find("invoices", invoice.id);
    if (inv) S.upsert("invoices", { ...inv, status: S.invoiceStatus(inv) });
    onClose();
  };
  return (
    <Modal title={t("doc.recordPayment")} size="lg" onClose={onClose}
      footer={<><Button variant="ghost" onClick={onClose}>{t("common.cancel")}</Button><Button variant="primary" icon="check" onClick={save}>{t("common.save")} + {t("nav.kwitansi")}</Button></>}>
      <div className="notice info" style={{ marginBottom: 18 }}><Icon name="kwitansi" size={16} /><div>{lang === "en" ? "A receipt (kwitansi) will be created automatically." : "Kwitansi akan dibuat otomatis dari pembayaran ini."} {t("col.outstanding")}: <strong>{S.formatRupiah(sisa)}</strong></div></div>
      <div className="form-grid">
        <Field label={t("common.date")}><Input type="date" value={f.date} onChange={(e) => set("date", e.target.value)} /></Field>
        <Field label={t("common.amount")}><MoneyInput value={f.amount} onChange={(v) => set("amount", v)} /></Field>
        <Field label={t("doc.method")}><Select value={f.method} onChange={(e) => set("method", e.target.value)}>{PAY_METHODS.map((m) => <option key={m} value={m}>{t("method." + m)}</option>)}</Select></Field>
        <Field label={lang === "en" ? "Bank" : "Bank"} optional><Input value={f.bank} onChange={(e) => set("bank", e.target.value)} /></Field>
        <Field label={t("doc.receivedFrom")} full><Input value={f.receivedFrom} onChange={(e) => set("receivedFrom", e.target.value)} /></Field>
        <Field label={t("doc.forPayment")} full><Textarea value={f.forPayment} onChange={(e) => set("forPayment", e.target.value)} /></Field>
      </div>
      <div className="notice warn" style={{ marginTop: 6 }}><Icon name="kwitansi" size={16} /><div className="serif" style={{ fontStyle: "italic" }}>{S.terbilang(f.amount, f.language)}</div></div>
    </Modal>
  );
}

/* ===================================================================
   KWITANSI (Receipt)
   =================================================================== */
function KwitansiList() {
  useStore();
  const [lang] = useLang();
  const [q, setQ] = useState(""); const [confirm, confirmNode] = useConfirm();
  let rows = S.all("payments").slice().sort((a, b) => (b.date || "").localeCompare(a.date || ""));
  if (q) rows = rows.filter((r) => (r.number + r.receivedFrom + S.projectName(r.projectId)).toLowerCase().includes(q.toLowerCase()));
  return (
    <div>
      <PageHead title={t("doc.kwitansi")} sub={lang === "en" ? "Receipts for payments received." : "Bukti penerimaan pembayaran."}>
        <Button variant="primary" icon="plus" onClick={() => go("#/dokumen/kwitansi/baru")}>{t("common.new")} {t("nav.kwitansi")}</Button>
      </PageHead>
      <div className="toolbar"><div className="search"><Icon name="search" className="ico" /><Input value={q} onChange={(e) => setQ(e.target.value)} placeholder={t("common.search")} /></div></div>
      <div className="card"><div className="table-wrap"><table className="tbl">
        <thead><tr><th>{t("common.number")}</th><th>{t("doc.receivedFrom")}</th><th>{t("common.project")}</th><th>{t("doc.method")}</th><th className="num">{t("common.amount")}</th><th>{t("common.date")}</th><th></th></tr></thead>
        <tbody>
          {rows.length === 0 && <tr><td colSpan="7"><Empty icon="kwitansi" title={t("common.empty")} /></td></tr>}
          {rows.map((r) => (
            <tr key={r.id} className="clickable" onClick={() => go("#/dokumen/kwitansi/" + r.id)}>
              <td className="mono" style={{ fontWeight: 600, fontSize: 12 }}>{r.number}</td>
              <td>{r.receivedFrom}</td><td>{S.projectName(r.projectId)}</td>
              <td><Badge tone="neutral">{t("method." + r.method)}</Badge></td>
              <td className="num" style={{ fontWeight: 600 }}>{S.formatRupiah(r.amount)}</td>
              <td>{S.shortDate(r.date)}</td>
              <td className="num" onClick={(e) => e.stopPropagation()}><Button variant="ghost" size="sm" icon="trash" onClick={() => confirm(t("common.confirmDelete"), () => S.remove("payments", r.id))} /></td>
            </tr>
          ))}
        </tbody>
      </table></div></div>
      {confirmNode}
    </div>
  );
}

function KwitansiEditor({ id, createNew }) {
  useStore();
  const [lang] = useLang();
  const qp = routeQuery(window.location.hash);
  const existing = id ? S.find("payments", id) : null;
  const invoices = S.all("invoices");
  const [doc, setDoc] = useState(existing || {
    number: "", date: S.todayISO(), invoiceId: qp.invoice || "", projectId: qp.project || "", amount: 0,
    receivedFrom: "", forPayment: "", method: "transfer", bank: S.getDB().company.bankName || "", language: lang, note: ""
  });
  if (id && !existing) return <Empty icon="kwitansi" title={t("common.empty")} action={<Button onClick={() => go("#/dokumen/kwitansi")}>{t("common.back")}</Button>} />;
  const set = (patch) => setDoc((o) => ({ ...o, ...patch }));
  const onPickInvoice = (invId) => {
    const inv = S.find("invoices", invId);
    if (inv) { const p = S.find("projects", inv.projectId); const c = p ? S.find("clients", p.clientId) : null;
      set({ invoiceId: invId, projectId: inv.projectId, receivedFrom: c ? c.name : doc.receivedFrom, forPayment: (inv.terminDesc || "") + " — " + (p ? p.name : "") + " (" + inv.number + ")" });
    } else set({ invoiceId: "" });
  };
  const save = () => { const s = saveDoc("payments", "payment", doc); setDoc(s); if (createNew) go("#/dokumen/kwitansi/" + s.id); };
  return (
    <div>
      <EditorHead backPath="#/dokumen/kwitansi" backLabel={t("doc.kwitansi")} code={doc.number || t("common.new")} title={t("doc.kwitansi")}
        statusNode={null}
        actions={<>
          {!createNew && doc.number && <Button icon="print" onClick={() => { save(); go("#/cetak/kwitansi/" + doc.id); }}>{t("common.print")}</Button>}
          <Button variant="primary" icon="check" onClick={save}>{t("common.save")}</Button>
        </>} />
      <div className="grid-2" style={{ alignItems: "start" }}>
        <div className="card pad">
          <div className="form-grid">
            <Field label={t("doc.relatedInvoice")} optional full>
              <Select value={doc.invoiceId || ""} onChange={(e) => onPickInvoice(e.target.value)}>
                <option value="">— {t("common.none")} —</option>
                {invoices.map((iv) => <option key={iv.id} value={iv.id}>{iv.number} · {S.projectName(iv.projectId)}</option>)}
              </Select>
            </Field>
            <Field label={t("common.project")}><ProjectSelect value={doc.projectId} onChange={(v) => set({ projectId: v })} /></Field>
            <Field label={t("common.documentLang")}><DocLangToggle value={doc.language} onChange={(v) => set({ language: v })} /></Field>
            <Field label={t("common.date")}><Input type="date" value={doc.date} onChange={(e) => set({ date: e.target.value })} /></Field>
            <Field label={t("doc.method")}><Select value={doc.method} onChange={(e) => set({ method: e.target.value })}>{PAY_METHODS.map((m) => <option key={m} value={m}>{t("method." + m)}</option>)}</Select></Field>
            <Field label="Bank" optional><Input value={doc.bank} onChange={(e) => set({ bank: e.target.value })} /></Field>
            <Field label={t("common.amount")}><MoneyInput value={doc.amount} onChange={(v) => set({ amount: v })} /></Field>
            <Field label={t("doc.receivedFrom")} full><Input value={doc.receivedFrom} onChange={(e) => set({ receivedFrom: e.target.value })} /></Field>
            <Field label={t("doc.forPayment")} full><Textarea value={doc.forPayment} onChange={(e) => set({ forPayment: e.target.value })} /></Field>
          </div>
        </div>
        <div className="card pad">
          <h2 className="section">{t("doc.terbilang")}</h2>
          <div className="serif" style={{ fontSize: 22, lineHeight: 1.2 }}>{S.formatRupiah(doc.amount)}</div>
          <div className="notice warn" style={{ marginTop: 14 }}><div className="serif" style={{ fontStyle: "italic" }}>{S.terbilang(doc.amount, doc.language)}</div></div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { InvoiceList, InvoiceEditor, KwitansiList, KwitansiEditor, RecordPaymentModal, PAY_METHODS });
