/* =========================================================================
   债务明细清单 · 页面（二）债务列表 / 债务详情 / 全部还款明细
   ========================================================================= */
(function () {
const { money, fmtDate, fmtDateTime, debtCalc, debtorCalc } = window.Ledger;

/* ===================== 债务列表 ===================== */
function DebtListPage({ state, go, openModal, initialFilter }) {
  const [status, setStatus] = React.useState(initialFilter || "all");
  const [debtorId, setDebtorId] = React.useState("");
  const [sort, setSort] = React.useState("remaining");
  const [q, setQ] = React.useState("");
  const [minAmount, setMinAmount] = React.useState("");
  const [maxAmount, setMaxAmount] = React.useState("");

  let rows = state.debts.map((d) => ({ d, c: debtCalc(state, d.id), debtor: state.debtors.find((x) => x.id === d.debtorId) }));
  if (q) rows = rows.filter((r) => (r.d.title + r.debtor.name + (r.d.note || "")).toLowerCase().includes(q.toLowerCase()));
  if (debtorId) rows = rows.filter((r) => r.d.debtorId === debtorId);
  if (minAmount) rows = rows.filter((r) => r.c.remaining >= window.Ledger.yuanToFen(minAmount));
  if (maxAmount) rows = rows.filter((r) => r.c.remaining <= window.Ledger.yuanToFen(maxAmount));
  if (status === "open") rows = rows.filter((r) => (r.c.remaining > 0 || r.c.amountPending) && !r.d.archived);
  if (status === "overdue") rows = rows.filter((r) => r.c.status === "已逾期");
  if (status === "settled") rows = rows.filter((r) => r.c.status === "已结清");
  if (status === "overpay") rows = rows.filter((r) => r.c.status === "存在多还款");
  rows.sort((a, b) => sort === "remaining" ? b.c.remaining - a.c.remaining : sort === "occur" ? new Date(b.d.occurDate) - new Date(a.d.occurDate) : new Date(a.d.dueDate || "2999") - new Date(b.d.dueDate || "2999"));

  const statusOpts = [["all", "全部"], ["open", "未结清"], ["overdue", "逾期"], ["settled", "已结清"], ["overpay", "多还款"]];
  const activeChips = [];
  if (debtorId) activeChips.push({ label: "欠款人：" + state.debtors.find((x) => x.id === debtorId).name, clear: () => setDebtorId("") });
  if (q) activeChips.push({ label: "搜索：" + q, clear: () => setQ("") });
  if (minAmount) activeChips.push({ label: "剩余≥¥" + minAmount, clear: () => setMinAmount("") });
  if (maxAmount) activeChips.push({ label: "剩余≤¥" + maxAmount, clear: () => setMaxAmount("") });

  return (
    <div className="page">
      <PageHeader title="债务" desc={`共 ${state.debts.length} 笔债务`}
        actions={<Btn kind="primary" icon="plus" onClick={() => openModal({ type: "debt" })}>新增债务</Btn>} />
      <div className="filterbar">
        <div className="search">
          <Icon name="search" size={16} className="muted" />
          <input placeholder="搜索债务标题、欠款人、备注" value={q} onChange={(e) => setQ(e.target.value)} />
        </div>
        <select className="inp-sm" value={debtorId} onChange={(e) => setDebtorId(e.target.value)}>
          <option value="">全部欠款人</option>
          {state.debtors.map((d) => <option key={d.id} value={d.id}>{d.name}</option>)}
        </select>
        <div className="seg seg-inline">
          {statusOpts.map(([k, l]) => <button key={k} className={"seg-btn " + (status === k ? "active" : "")} onClick={() => setStatus(k)}>{l}</button>)}
        </div>
        <input className="inp-sm amount-filter" inputMode="decimal" placeholder="剩余最低" value={minAmount} onChange={(e) => setMinAmount(e.target.value.replace(/[^\d.]/g, ""))} />
        <input className="inp-sm amount-filter" inputMode="decimal" placeholder="剩余最高" value={maxAmount} onChange={(e) => setMaxAmount(e.target.value.replace(/[^\d.]/g, ""))} />
        <div className="grow" />
        <label className="sort-sel">排序<select value={sort} onChange={(e) => setSort(e.target.value)}><option value="remaining">剩余待还</option><option value="occur">发生日期</option><option value="due">约定日期</option></select></label>
      </div>
      {activeChips.length > 0 && <div className="chips-row">{activeChips.map((c, i) => <FilterChip key={i} label={c.label} onClear={c.clear} />)}<button className="link" onClick={() => { setDebtorId(""); setQ(""); setMinAmount(""); setMaxAmount(""); setStatus("all"); }}>清空筛选</button></div>}

      {rows.length === 0 ? (
        state.debts.length === 0
          ? <EmptyState icon="debt" title="还没有债务记录" desc="为欠款人新增第一笔债务" action={<Btn kind="primary" icon="plus" onClick={() => openModal({ type: "debt" })}>新增债务</Btn>} />
          : <EmptyState icon="search" title="没有符合条件的债务" action={<Btn kind="outline" size="sm" onClick={() => { setStatus("all"); setDebtorId(""); setQ(""); }}>清空筛选</Btn>} />
      ) : (
        <div className="card no-pad">
          <table className="dtable dtable-rows">
            <thead><tr><th>债务标题</th><th>欠款人</th><th>发生日期</th><th>约定日期</th><th className="ta-r">当前应还</th><th className="ta-r">累计已还</th><th className="ta-r">剩余待还</th><th className="ta-c">状态</th></tr></thead>
            <tbody>
              {rows.map(({ d, c, debtor }) => (
                <tr key={d.id} className={"clickable " + (c.status === "已结清" ? "row-dim" : "")} onClick={() => go({ page: "debt", id: d.id })}>
                  <td><div className="strong">{d.title}</div><div className="muted xs"><span className="tag-soft xs">{d.type}</span></div></td>
                  <td><div className="cell-name"><Avatar name={debtor.name} size={26} />{debtor.name}</div></td>
                  <td className="num muted">{fmtDate(d.occurDate)}</td>
                  <td className={"num " + (c.status === "已逾期" ? "red" : "muted")}>{fmtDate(d.dueDate)}</td>
                  <td className="ta-r num">{money(c.currentDue)}</td>
                  <td className="ta-r num green">{money(c.paid)}</td>
                  <td className="ta-r num strong">{c.amountPending ? "待补充" : money(c.remaining)}</td>
                  <td className="ta-c"><StatusBadge status={c.status} size="sm" /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

/* ===================== 债务详情 ===================== */
function DebtDetailPage({ state, id, go, openModal, actions }) {
  const [moreOpen, setMoreOpen] = React.useState(false);
  const d = state.debts.find((x) => x.id === id);
  if (!d) return <div className="page"><EmptyState title="债务不存在" action={<Btn onClick={() => go({ page: "debts" })}>返回列表</Btn>} /></div>;
  const c = debtCalc(state, id);
  const debtor = state.debtors.find((x) => x.id === d.debtorId);
  const timeline = window.buildDebtTimeline(state, id);

  return (
    <div className="page">
      <button className="breadcrumb" onClick={() => go({ page: "debtor", id: debtor.id })}><Icon name="back" size={15} />{debtor.name}</button>
      <div className="detail-head">
        <div className="dh-left">
          <div>
            <div className="dh-name">{d.title}<StatusBadge status={c.status} /></div>
            <div className="dh-contacts">
              <span className="clickable link" onClick={() => go({ page: "debtor", id: debtor.id })}><Icon name="users" size={13} />{debtor.name}</span>
              <span className="tag-soft">{d.type}</span>
              {d.dueDate && <span className={c.status === "已逾期" ? "red" : "muted"}><Icon name="calendar" size={13} />约定 {fmtDate(d.dueDate)}{c.status === "已逾期" ? `（已逾期 ${-c.dueIn} 天）` : ""}</span>}
            </div>
          </div>
        </div>
        <div className="dh-actions">
          <div className="more-wrap">
            <Btn kind="ghost" icon="more" onClick={() => setMoreOpen(!moreOpen)}>更多</Btn>
            {moreOpen && (
              <div className="menu" onMouseLeave={() => setMoreOpen(false)}>
                <button onClick={() => { setMoreOpen(false); openModal({ type: "debt", edit: d }); }}><Icon name="edit" size={15} />编辑债务</button>
                <button onClick={() => { setMoreOpen(false); openModal({ type: "adjust", debtId: id }); }}><Icon name="coins" size={15} />金额调整</button>
                <button onClick={() => { setMoreOpen(false); actions.archiveDebt(id); }}><Icon name="archive" size={15} />{d.archived ? "取消归档" : "归档债务"}</button>
              </div>
            )}
          </div>
          <Btn kind="outline" icon="coins" onClick={() => openModal({ type: "adjust", debtId: id })}>金额调整</Btn>
          <Btn kind="primary" icon="plus" onClick={() => openModal({ type: "payment", preset: { debtorId: debtor.id, debtId: id } })}>记一笔还款</Btn>
        </div>
      </div>

      {c.status === "存在多还款" && (
        <div className="alert-bar ab-amber"><Icon name="alert" size={18} /><div><b>存在多还款</b>：累计已还超过当前应还，多还 <span className="num">{money(-c.remaining)}</span>，请人工确认是否退款或转入其他债务。</div></div>
      )}
      {c.amountPending && (
        <div className="alert-bar ab-amber"><Icon name="alert" size={18} /><div><b>原始欠款金额待补充</b>：当前金额暂按已导入的累计还款 <span className="num">{money(c.paid)}</span> 建立。请点击“更多 → 编辑债务”填写真实原始欠款总额，系统会自动计算剩余待还。</div></div>
      )}

      <div className="amt-row amt-row-4">
        <AmountCard label="原始应还金额" fen={c.principal} />
        <AmountCard label="当前应还总额" fen={c.currentDue} hint={c.increase || c.reduce ? `原始 ${money(c.principal)}${c.increase ? ` +增 ${money(c.increase)}` : ""}${c.reduce ? ` -减 ${money(c.reduce)}` : ""}` : "无调整"} />
        <AmountCard tone="green" label="累计已还" fen={c.paid} hint={`${c.payCount} 笔有效还款`} />
        <AmountCard primary tone="brand" label="剩余待还" fen={c.remaining} display={c.amountPending ? "金额待补充" : null} />
      </div>

      <div className="card">
        <div className="card-head"><div className="card-title">还款进度</div><span className="muted">{c.payCount} 笔还款</span></div>
        <Progress value={c.progress} paid={c.paid} due={c.currentDue} tone={c.status === "已逾期" ? "red" : c.status === "已结清" ? "green" : "blue"} />
      </div>

      <div className="grid-2 grid-2-37">
        <div className="card">
          <div className="card-head"><div className="card-title">明细时间线</div></div>
          <Timeline items={timeline} />
        </div>
        <div className="side-stack">
          <div className="card">
            <div className="card-title sm">债务信息</div>
            <div className="info-list">
              {[["发生日期", fmtDate(d.occurDate)], ["约定还款日期", d.dueDate ? fmtDate(d.dueDate) : "—"], ["债务类型", d.type], ["是否计息", d.interest ? "计息" : "不计息"], ...(d.interest ? [["利息说明", d.interestNote || "—"]] : []), ["来源说明", d.source || "—"], ["备注", d.note || "—"]].map(([k, v]) => (
                <div className="info-row" key={k}><span className="info-k">{k}</span><span className="info-v">{v}</span></div>
              ))}
            </div>
          </div>
          <div className="card">
            <div className="card-title sm">附件凭证</div>
            {d.attachments && d.attachments.length ? (
              <div className="attach-list">
                {d.attachments.map((a, i) => (
                  <div className="attach-item" key={i}>
                    <span className="attach-thumb"><Icon name={a.kind === "image" ? "image" : "file"} size={18} /></span>
                    <div className="attach-info"><div className="attach-name">{a.name}</div><div className="muted xs">{a.size}</div></div>
                    <button className="iconbtn-xs" onClick={() => window.downloadLedgerAttachment(a)}><Icon name="download" size={15} /></button>
                  </div>
                ))}
              </div>
            ) : <EmptyState compact icon="file" title="暂无附件" desc="编辑债务可上传合同、借条等" />}
          </div>
          <AdjustmentPanel state={state} debtId={id} actions={actions} />
        </div>
      </div>
    </div>
  );
}

function AdjustmentPanel({ state, debtId, actions }) {
  const rows = state.adjustments.filter((a) => a.debtId === debtId).sort((a, b) => new Date(b.date) - new Date(a.date));
  if (!rows.length) return <div className="card"><div className="card-title sm">金额调整记录</div><EmptyState compact icon="coins" title="暂无调整" desc="追加债务或减免金额后会显示在这里" /></div>;
  return (
    <div className="card">
      <div className="card-title sm">金额调整记录</div>
      <div className="adjust-list">
        {rows.map((a) => (
          <div className={"adjust-row " + (a.status === "void" ? "is-void" : "")} key={a.id}>
            <div>
              <div className="strong">{a.type === "increase" ? "增加应还" : "减免应还"} <span className="num">{money(a.amountFen)}</span></div>
              <div className="muted xs">{fmtDate(a.date)} · {a.reason}{a.voidReason ? ` · 作废原因：${a.voidReason}` : ""}</div>
            </div>
            <div className="row-actions">
              <StatusBadge status={a.status === "void" ? "已作废" : "有效"} size="sm" />
              {a.status === "void"
                ? <button className="link" onClick={() => actions.restoreAdjustment(a.id)}>恢复</button>
                : <button className="link danger" onClick={() => { const reason = prompt("请输入作废金额调整的原因"); if (reason && reason.trim()) actions.voidAdjustment(a.id, reason.trim()); }}>作废</button>}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

window.buildDebtTimeline = function (state, debtId) {
  const items = [];
  const debt = state.debts.find((x) => x.id === debtId);
  state.payments.filter((p) => p.debtId === debtId).forEach((p) => {
    items.push({ ts: p.datetime, tone: p.status === "void" ? "neutral" : "green", void: p.status === "void", icon: "receipt", title: p.status === "void" ? "还款（已作废）" : "收到还款", amount: p.amountFen, amountClass: p.status === "void" ? "void" : "green", sub: `${fmtDateTime(p.datetime)} · ${p.channel}${p.txnNo ? " · 流水 " + p.txnNo : ""}`, note: p.status === "void" ? `作废原因：${p.voidReason}` : p.note });
  });
  state.adjustments.filter((a) => a.debtId === debtId).forEach((a) => {
    items.push({ ts: a.date, tone: a.status === "void" ? "neutral" : (a.type === "increase" ? "amber" : "blue"), void: a.status === "void", icon: "coins", title: (a.type === "increase" ? "增加应还金额" : "减免应还金额") + (a.status === "void" ? "（已作废）" : ""), amount: a.amountFen, amountClass: a.status === "void" ? "void" : "", sub: `${fmtDate(a.date)} · ${a.reason}`, note: a.voidReason ? `作废原因：${a.voidReason}` : "" });
  });
  items.push({ ts: debt.createdAt, tone: "blue", icon: "debt", title: "创建债务", amount: debt.principalFen, sub: `${fmtDate(debt.occurDate)} · 原始应还金额` });
  return items.sort((a, b) => new Date(b.ts) - new Date(a.ts));
};

/* ===================== 全部还款明细 ===================== */
function PaymentListPage({ state, actions, go, openModal }) {
  const [debtorId, setDebtorId] = React.useState("");
  const [debtId, setDebtId] = React.useState("");
  const [channel, setChannel] = React.useState("");
  const [statusF, setStatusF] = React.useState("valid");
  const [q, setQ] = React.useState("");
  const [startDate, setStartDate] = React.useState("");
  const [endDate, setEndDate] = React.useState("");
  const [minAmount, setMinAmount] = React.useState("");
  const [maxAmount, setMaxAmount] = React.useState("");
  const [attachF, setAttachF] = React.useState("all");

  let rows = [...state.payments].map((p) => ({ p, debtor: state.debtors.find((x) => x.id === p.debtorId), debt: state.debts.find((x) => x.id === p.debtId) }));
  if (debtorId) rows = rows.filter((r) => r.p.debtorId === debtorId);
  if (debtId) rows = rows.filter((r) => r.p.debtId === debtId);
  if (channel) rows = rows.filter((r) => r.p.channel === channel);
  if (statusF !== "all") rows = rows.filter((r) => r.p.status === statusF);
  if (startDate) rows = rows.filter((r) => new Date(r.p.datetime) >= new Date(startDate + "T00:00:00"));
  if (endDate) rows = rows.filter((r) => new Date(r.p.datetime) <= new Date(endDate + "T23:59:59"));
  if (minAmount) rows = rows.filter((r) => r.p.amountFen >= window.Ledger.yuanToFen(minAmount));
  if (maxAmount) rows = rows.filter((r) => r.p.amountFen <= window.Ledger.yuanToFen(maxAmount));
  if (attachF === "yes") rows = rows.filter((r) => r.p.hasAttach);
  if (attachF === "no") rows = rows.filter((r) => !r.p.hasAttach);
  if (q) rows = rows.filter((r) => ((r.p.txnNo || "") + r.debtor.name + r.debt.title + (r.p.note || "")).toLowerCase().includes(q.toLowerCase()));
  rows.sort((a, b) => new Date(b.p.datetime) - new Date(a.p.datetime));

  const total = rows.filter((r) => r.p.status === "valid").reduce((s, r) => s + r.p.amountFen, 0);
  const chips = [];
  if (debtorId) chips.push({ label: "欠款人：" + state.debtors.find((x) => x.id === debtorId).name, clear: () => setDebtorId("") });
  if (debtId) chips.push({ label: "债务：" + state.debts.find((x) => x.id === debtId).title, clear: () => setDebtId("") });
  if (channel) chips.push({ label: "途径：" + channel, clear: () => setChannel("") });
  if (q) chips.push({ label: "搜索：" + q, clear: () => setQ("") });
  if (startDate) chips.push({ label: "开始：" + startDate, clear: () => setStartDate("") });
  if (endDate) chips.push({ label: "结束：" + endDate, clear: () => setEndDate("") });
  if (minAmount) chips.push({ label: "金额≥¥" + minAmount, clear: () => setMinAmount("") });
  if (maxAmount) chips.push({ label: "金额≤¥" + maxAmount, clear: () => setMaxAmount("") });
  if (attachF !== "all") chips.push({ label: attachF === "yes" ? "有凭证" : "无凭证", clear: () => setAttachF("all") });

  return (
    <div className="page">
      <PageHeader title="还款明细" desc="全部还款记录，支持筛选、查看凭证、作废"
        actions={<><Btn kind="outline" icon="download" onClick={() => openModal({ type: "export", scope: "当前筛选结果", data: { ...state, payments: rows.map((r) => r.p) } })}>导出当前结果</Btn><Btn kind="primary" icon="plus" onClick={() => openModal({ type: "payment" })}>记一笔还款</Btn></>} />

      <div className="summary-strip">
        <div><span className="ss-label">筛选范围内回款总额</span><span className="num ss-amt green">{money(total)}</span></div>
        <div className="ss-div" />
        <div><span className="ss-label">记录条数</span><span className="num ss-n">{rows.length}</span></div>
      </div>

      <div className="filterbar">
        <div className="search"><Icon name="search" size={16} className="muted" /><input placeholder="搜索流水号、欠款人、债务、备注" value={q} onChange={(e) => setQ(e.target.value)} /></div>
        <select className="inp-sm" value={debtorId} onChange={(e) => { setDebtorId(e.target.value); setDebtId(""); }}><option value="">全部欠款人</option>{state.debtors.map((d) => <option key={d.id} value={d.id}>{d.name}</option>)}</select>
        <select className="inp-sm" value={debtId} onChange={(e) => setDebtId(e.target.value)}><option value="">全部债务</option>{state.debts.filter((d) => !debtorId || d.debtorId === debtorId).map((d) => <option key={d.id} value={d.id}>{d.title}</option>)}</select>
        <select className="inp-sm" value={channel} onChange={(e) => setChannel(e.target.value)}><option value="">全部途径</option>{state.channels.map((c) => <option key={c}>{c}</option>)}</select>
        <input type="date" className="inp-sm" value={startDate} onChange={(e) => setStartDate(e.target.value)} />
        <input type="date" className="inp-sm" value={endDate} onChange={(e) => setEndDate(e.target.value)} />
        <input className="inp-sm amount-filter" inputMode="decimal" placeholder="最低金额" value={minAmount} onChange={(e) => setMinAmount(e.target.value.replace(/[^\d.]/g, ""))} />
        <input className="inp-sm amount-filter" inputMode="decimal" placeholder="最高金额" value={maxAmount} onChange={(e) => setMaxAmount(e.target.value.replace(/[^\d.]/g, ""))} />
        <select className="inp-sm" value={attachF} onChange={(e) => setAttachF(e.target.value)}><option value="all">全部凭证</option><option value="yes">有凭证</option><option value="no">无凭证</option></select>
        <div className="seg seg-inline">
          {[["valid", "有效"], ["void", "已作废"], ["all", "全部"]].map(([k, l]) => <button key={k} className={"seg-btn " + (statusF === k ? "active" : "")} onClick={() => setStatusF(k)}>{l}</button>)}
        </div>
      </div>
      {chips.length > 0 && <div className="chips-row">{chips.map((c, i) => <FilterChip key={i} label={c.label} onClear={c.clear} />)}<button className="link" onClick={() => { setDebtorId(""); setDebtId(""); setChannel(""); setQ(""); setStartDate(""); setEndDate(""); setMinAmount(""); setMaxAmount(""); setAttachF("all"); setStatusF("valid"); }}>清空筛选</button></div>}

      {rows.length === 0 ? (
        <EmptyState icon="receipt" title="没有还款记录" desc={state.payments.length === 0 ? "收到还款后，在此快速登记" : "没有符合当前筛选条件的记录"} action={state.payments.length === 0 ? <Btn kind="primary" icon="plus" onClick={() => openModal({ type: "payment" })}>记一笔还款</Btn> : <Btn kind="outline" size="sm" onClick={() => { setDebtorId(""); setChannel(""); setQ(""); setStatusF("valid"); }}>清空筛选</Btn>} />
      ) : (
        <div className="card no-pad">
          <table className="dtable dtable-rows">
            <thead><tr><th>日期时间</th><th>欠款人</th><th>债务</th><th>途径</th><th>流水号</th><th className="ta-r">金额</th><th className="ta-c">凭证</th><th className="ta-c">状态</th><th className="ta-r">操作</th></tr></thead>
            <tbody>
              {rows.map(({ p, debtor, debt }) => (
                <tr key={p.id} className={p.status === "void" ? "row-void" : ""}>
                  <td className="num muted">{fmtDateTime(p.datetime)}</td>
                  <td><div className="cell-name"><Avatar name={debtor.name} size={24} />{debtor.name}</div></td>
                  <td className="clickable link" onClick={() => go({ page: "debt", id: p.debtId })}>{debt.title}</td>
                  <td><span className="tag-soft">{p.channel}</span></td>
                  <td className="num muted xs">{p.txnNo || "—"}</td>
                  <td className={"ta-r num strong " + (p.status === "void" ? "strike" : "green")}>{money(p.amountFen)}</td>
                  <td className="ta-c">{p.hasAttach ? <button className="iconbtn-xs" title={p.attachmentName || "下载凭证"} onClick={() => window.downloadLedgerAttachment(p.attachment || { name: p.attachmentName })}><Icon name="image" size={15} /></button> : <span className="muted">—</span>}</td>
                  <td className="ta-c"><StatusBadge status={p.status === "void" ? "已作废" : "有效"} size="sm" /></td>
                  <td className="ta-r">
                    <div className="row-actions">
                      {p.status === "valid" ? <>
                        <button className="link" onClick={() => openModal({ type: "payment", edit: p })}>编辑</button>
                        <button className="link danger" onClick={() => openModal({ type: "void", payment: p })}>作废</button>
                      </> : <button className="link" title={p.voidReason} onClick={() => { actions.restorePayment(p.id); }}>恢复</button>}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { DebtListPage, DebtDetailPage, PaymentListPage, AdjustmentPanel });
})();
