// ===== Printable statement for a single agent / group =====
// 對帳單口徑 (與月度總覽/主播明細不同):
//   bonus = bRank + bActive + bIncr + bOff263   (只這 4 項)
//   排除的項目 (公會/平台保留, 不列入對帳單):
//     bMatureRank  成熟創作者晉升率
//     bMatureMaint 成熟主播維持
//     bTiers       維持等級
//     bOff         站外主播任務 (舊)
// 「站外主播任務 (2026.3)」bOff263: 有數字 = 資格通過, 直接列入
const STMT_KEYS = ['bRank', 'bActive', 'bIncr', 'bOff263'];
// 但 bOff263 不在 BONUS_PARTS 裡, 補一個定義給對帳單專用區塊
const STMT_PARTS = [
  BONUS_PARTS.find((p) => p.key === 'bRank'),
  BONUS_PARTS.find((p) => p.key === 'bActive'),
  BONUS_PARTS.find((p) => p.key === 'bIncr'),
  { key: 'bOff263', label: '站外主播任務', en: 'Off-platform creator task (2026.3)', color: 'oklch(0.6 0.14 340)' },
];

// 對帳單專用: 依 STMT_KEYS 重新算 bonus / payout / payoutTWD
// 順便掛上「結算方式服務費」(feeRate / feeTWD, 依所屬群組):
//   invoice = 0%, labor = 5%
// 服務費 TWD = round(payout USD × feeRate × fx)
const adjustForStmt = (r, fx, invoiceMap) => {
  const bonus = STMT_KEYS.reduce((s, k) => s + (r[k] || 0), 0);
  const payout = Math.round(bonus * (r.shareRate || 0) / 100 * 10000) / 10000;
  const payoutTWD = Math.round(payout * (fx || 0));
  const invoiceType = getInvoiceType(invoiceMap, r.group || '');
  const feeRate = feeRateOf(invoiceType);
  const feeTWD = feeRate > 0 ? Math.round(payout * feeRate * (fx || 0)) : 0;
  return { ...r, bonus, payout, payoutTWD, invoiceType, feeRate, feeTWD };
};

// ---- 額外獎金 (Extra bonuses) ----
// 從 D1 拉, 由 App 管 state; 這裡透過 props 收 extrasMap / onAddExtra / onRemoveExtra.

function StatementView({ rows, month, dim, name, setName, status, setStatus,
                        invoiceMap, setInvoice, extrasMap, onAddExtra, onRemoveExtra }) {
  const dimLabel = DIMENSIONS.find((d) => d.key === dim).label;
  const fx = window.RECON_FX;

  // 對帳單專用: 每列依 STMT_KEYS 重算 bonus/payout, 並附上服務費
  const stmtRows = React.useMemo(
    () => rows.map((r) => adjustForStmt(r, fx, invoiceMap)),
    [rows, fx, invoiceMap]
  );
  const groups = React.useMemo(() => aggregate(stmtRows, dim).sort((a, b) => b.payout - a.payout), [stmtRows, dim]);
  const g = groups.find((x) => x.name === name) || groups[0];
  const [showZero, setShowZero] = React.useState(false);
  if (!g) return <div className="view"><div className="empty">無資料</div></div>;

  const lines = [...g.rows].sort((a, b) => b.payout - a.payout);
  const shown = showZero ? lines : lines.filter((r) => r.diamonds > 0 || r.bonus > 0);
  const hidden = lines.length - shown.length;
  const key = `${month}|${dim}|${g.name}`;
  const y = month.slice(0, 4), m = parseInt(month.slice(4), 10);
  const lastDay = new Date(+y, m, 0).getDate();
  const stmtNo = `ST-${month}-${dim.toUpperCase()}-${String(groups.indexOf(g) + 1).padStart(3, '0')}`;
  const parts = STMT_PARTS.map((p) => ({ ...p, v: sumBy(g.rows, p.key) }));

  // 服務費 (逐筆算再加總, 讓經紀人/群組經理維度也能正確算跨群組)
  const feeTotalTWD = g.rows.reduce((s, r) => s + (r.feeTWD || 0), 0);

  // 統計對帳單裡涉及幾個群組, 各種結算方式的分佈 (跨群組維度時很重要)
  const groupNames = [...new Set(g.rows.map((r) => r.group || ''))];
  const invoiceCounts = { invoice: 0, labor: 0 };
  for (const gn of groupNames) invoiceCounts[getInvoiceType(invoiceMap, gn)]++;
  const isMultiGroup = groupNames.length > 1;
  // 群組維度 → 對象=群組本身, 直接以該群組的結算方式為主
  const primaryInvoiceType = dim === 'group'
    ? getInvoiceType(invoiceMap, g.name || '')
    : (invoiceCounts.labor > 0 ? 'labor' : 'invoice'); // 跨群組: 有勞報單就標記為 mixed/labor

  // 額外獎金: 資料來自 App (D1). 這裡只讀 extrasMap, 增刪呼叫 App 傳來的 handler.
  const extras = extrasMap?.[key] || [];
  const extrasTotal = extras.reduce((s, x) => s + (Number(x.amount) || 0), 0);
  // 最終公式: 分潤匯款 − 服務費 + 額外獎金
  const finalTWD = g.payoutTWD - feeTotalTWD + extrasTotal;
  const addExtra = (label, amount) => onAddExtra && onAddExtra(month, dim, g.name || '', label.trim() || '額外獎金', amount);
  const removeExtra = (id) => onRemoveExtra && onRemoveExtra(month, dim, g.name || '', id);

  const invoiceLabel = (t) => (INVOICE_TYPES.find((x) => x.v === t) || INVOICE_TYPES[0]).label;

  const exportCSV = () => {
    // 主表
    const header = ['Creator ID', '暱稱', 'Handle', '群組', '結算方式', '鑽石', '有效天數', '直播時數', ...STMT_PARTS.map((p) => p.label), '預估獎金', '分潤類型', '分潤比例', '應付分潤 USD', '匯率', '匯款 TWD', '服務費 TWD'];
    const body = lines.map((r) => [r.id, r.nick, r.handle, r.group || '', invoiceLabel(r.invoiceType), r.diamonds, r.days, r.hours, ...STMT_PARTS.map((p) => r[p.key] ?? ''), r.bonus, r.shareType, r.shareRate + '%', r.payout, window.RECON_FX, r.payoutTWD, r.feeTWD || 0]);
    // 追加: 額外獎金段
    const tail = [];
    if (extras.length) {
      tail.push([]);
      tail.push(['額外獎金 (直接匯付 TWD)']);
      tail.push(['項目', '金額 TWD']);
      for (const x of extras) tail.push([x.label, x.amount]);
      tail.push(['小計', extrasTotal]);
    }
    // 結算欄
    tail.push([]);
    tail.push(['分潤匯款小計 TWD', g.payoutTWD]);
    if (feeTotalTWD > 0) tail.push([`勞報單服務費 (-${(LABOR_FEE_RATE * 100).toFixed(0)}%)`, -feeTotalTWD]);
    if (extras.length) tail.push(['額外獎金小計 TWD', extrasTotal]);
    tail.push(['本期應匯款總額 TWD', finalTWD]);
    tail.push(['結算方式', dim === 'group' ? invoiceLabel(primaryInvoiceType) : `跨群組 (發票 ${invoiceCounts.invoice} / 勞報單 ${invoiceCounts.labor})`]);
    downloadCSV(`對帳單_${g.name || '未指定'}_${month}.csv`, header, [...body, ...tail]);
  };

  return (
    <div className="view">
      <div className="stmt-bar no-print">
        <select className="select select-lg" value={g.name} onChange={(e) => setName(e.target.value)}>
          {groups.map((x) => {
            const ex = ((extrasMap && extrasMap[`${month}|${dim}|${x.name}`]) || []).reduce((s, e) => s + (Number(e.amount) || 0), 0);
            const fee = x.rows.reduce((s, r) => s + (r.feeTWD || 0), 0);
            return <option key={x.name} value={x.name}>{x.name || '(未指定)'} — {fmtTWD(x.payoutTWD - fee + ex)}{(ex || fee) ? ' *' : ''}</option>;
          })}
        </select>
        <StatusPill value={status[key]} onChange={(v) => setStatus(key, v)} />
        {/* 結算方式 seg: 只在「依群組」時 (對象=群組本身) 直接切換該群組的設定;
            其他維度時, 因為對象跨多群組, 顯示唯讀分佈 */}
        {dim === 'group' ? (
          <div className="seg" title="結算方式（發票免服務費 / 勞報單 5%）">
            {INVOICE_TYPES.map((it) => (
              <button key={it.v}
                className={primaryInvoiceType === it.v ? 'on' : ''}
                onClick={() => setInvoice(g.name || '', it.v)}>
                {it.label}
              </button>
            ))}
          </div>
        ) : (
          <span className="muted" style={{fontSize:12}}>
            結算：{invoiceCounts.invoice > 0 && `發票 ${invoiceCounts.invoice}`}
            {invoiceCounts.invoice > 0 && invoiceCounts.labor > 0 && ' · '}
            {invoiceCounts.labor > 0 && `勞報單 ${invoiceCounts.labor}`}
            {' 群組'}
          </span>
        )}
        <label className="check"><input type="checkbox" checked={showZero} onChange={(e) => setShowZero(e.target.checked)} />顯示零收益主播</label>
        <div className="spacer" />
        <button className="btn ghost" onClick={exportCSV}>匯出 CSV</button>
        <button className="btn primary" onClick={() => window.print()}>列印 / 存成 PDF</button>
      </div>

      <article className="paper">
        <div className="paper-brand">
          <img src="/static/recon/assets/logo-full.png" alt="JDi 脈動傳媒" />
        </div>
        <header className="paper-head">
          <div>
            <div className="eyebrow">月結對帳單 · Monthly Statement</div>
            <h1>{g.name || '(未指定)'}</h1>
            <div className="muted">{dimLabel}</div>
          </div>
          <dl className="meta">
            <div><dt>對帳單號</dt><dd className="num">{stmtNo}</dd></div>
            <div><dt>結算期間</dt><dd className="num">{y}/{String(m).padStart(2, '0')}/01 – {y}/{String(m).padStart(2, '0')}/{lastDay}</dd></div>
            <div><dt>匯率</dt><dd className="num">1 USD = {window.RECON_FX} TWD</dd></div>
            <div><dt>產出日期</dt><dd className="num">{new Date().toLocaleDateString('zh-TW')}</dd></div>
          </dl>
        </header>

        <section className="paper-sum">
          <div className="sum-main">
            <span>本期應匯款金額（新台幣）</span>
            <b className="num">{fmtTWD(finalTWD)}</b>
            <small className="num">
              分潤匯款 {fmtTWD(g.payoutTWD)}
              {feeTotalTWD > 0 && <> − 勞報單服務費 {(LABOR_FEE_RATE * 100).toFixed(0)}% {fmtTWD(feeTotalTWD)}</>}
              {extras.length > 0 && <> ＋ 額外獎金 {fmtTWD(extrasTotal)}（{extras.length} 筆）</>}
            </small>
            <small className="num" style={{marginTop:4}}>
              應付 {fmtMoney(g.payout)} × 匯率 {window.RECON_FX}，預估獎金 {fmtMoney(g.bonus)} 依分潤比例計算{g.guild > 0 ? `，含公會代運營 ${g.guild} 位` : ''}
            </small>
            <small className="num" style={{marginTop:4}}>
              結算方式：{dim === 'group'
                ? (primaryInvoiceType === 'labor' ? '勞報單（收 5% 服務費）' : '發票（免服務費）')
                : `跨 ${groupNames.length} 個群組（發票 ${invoiceCounts.invoice} · 勞報單 ${invoiceCounts.labor}）`}
            </small>
          </div>
          <div className="sum-cells">
            <div><span>主播數</span><b className="num">{g.count}</b></div>
            <div><span>有收益主播</span><b className="num">{g.earning}</b></div>
            <div><span>鑽石</span><b className="num">{fmtInt(g.diamonds)}</b></div>
            <div><span>直播時數</span><b className="num">{fmtHr(g.hours)}</b></div>
          </div>
        </section>

        <section className="paper-parts">
          {parts.map((p) => (
            <div key={p.key} className={p.v ? '' : 'zero'}>
              <span><i className="dot" style={{ background: p.color }} />{p.label}{p.key === 'bIncr' && <em className="muted" style={{fontStyle:'normal',marginLeft:6}}>（鑽石 × {window.RECON_RATE}%）</em>}</span>
              <b className="num">{fmtMoney(p.v)}</b>
            </div>
          ))}
        </section>

        <ExtraBonusSection extras={extras} onAdd={addExtra} onRemove={removeExtra} total={extrasTotal} />

        <table className="tbl tbl-paper">
          <thead>
            <tr>
              <th className="idx">#</th>
              <th>主播</th>
              <th className="r">鑽石</th>
              <th className="r">天數</th>
              <th className="r">時數</th>
              <th className="r">躍升</th>
              <th className="r">活躍</th>
              <th className="r">增量收益<br/><span className="muted" style={{fontWeight:400}}>鑽石×{window.RECON_RATE}%</span></th>
              <th className="r">預估獎金</th>
              <th className="r">分潤</th>
              <th className="r">應付 USD</th>
              <th className="r">匯款 TWD</th>
            </tr>
          </thead>
          <tbody>
            {shown.map((r, i) => (
              <tr key={r.id}>
                <td className="idx num muted">{i + 1}</td>
                <td>
                  <div className="creator">
                    <span className="name">{r.nick}{r.violative && <b className="tag tag-red">違規</b>}</span>
                    <span className="handle num">@{r.handle} · {r.id}</span>
                  </div>
                </td>
                <td className="r num">{fmtInt(r.diamonds)}</td>
                <td className="r num">{r.days}</td>
                <td className="r num">{fmtHr(r.hours)}</td>
                <td className="r num">{r.bRank ? fmtMoney(r.bRank) : '—'}</td>
                <td className="r num">{r.bActive ? fmtMoney(r.bActive) : '—'}</td>
                <td className="r num">{r.bIncr ? fmtMoney(r.bIncr) : '—'}</td>
                <td className="r num">{fmtMoney(r.bonus)}</td>
                <td className="r"><ShareBadge r={r} /></td>
                <td className="r num">{fmtMoney(r.payout)}</td>
                <td className="r num strong">{fmtTWD(r.payoutTWD)}</td>
              </tr>
            ))}
            {!shown.length && <tr><td colSpan={12} className="empty">本期無收益主播</td></tr>}
          </tbody>
          <tfoot>
            <tr>
              <td></td>
              <td>合計{hidden > 0 && <span className="muted">（另有 {hidden} 位零收益主播未列出）</span>}</td>
              <td className="r num">{fmtInt(g.diamonds)}</td>
              <td></td>
              <td className="r num">{fmtHr(g.hours)}</td>
              <td className="r num">{fmtMoney(parts[0].v)}</td>
              <td className="r num">{fmtMoney(parts[1].v)}</td>
              <td className="r num">{fmtMoney(parts[2].v)}</td>
              <td className="r num">{fmtMoney(g.bonus)}</td>
              <td></td>
              <td className="r num">{fmtMoney(g.payout)}</td>
              <td className="r num strong">{fmtTWD(g.payoutTWD)}</td>
            </tr>
          </tfoot>
        </table>

        <footer className="paper-foot">
          <p>請於收到對帳單後 7 日內確認明細；如有疑義請回覆運營窗口，逾期視為確認無誤。</p>
          <div className="signs">
            <div><span>運營核對</span></div>
            <div><span>{dimLabel}確認</span></div>
          </div>
        </footer>
        {/* 列印浮水印：只在紙本上淡淡浮現 */}
        <div className="paper-watermark" aria-hidden>
          <img src="/static/recon/assets/logo-mark.png" alt="" />
        </div>
      </article>
    </div>
  );
}

// 額外獎金區塊：印刷時保留內容（項目 + 金額 + 小計），
// 但隱藏「新增/刪除」按鈕；沒有筆數時列印段整段不顯示。
function ExtraBonusSection({ extras, onAdd, onRemove, total }) {
  const [adding, setAdding] = React.useState(false);
  const [label, setLabel] = React.useState('');
  const [amount, setAmount] = React.useState('');
  const labelRef = React.useRef();
  React.useEffect(() => { if (adding && labelRef.current) labelRef.current.focus(); }, [adding]);
  const submit = () => {
    const n = parseFloat(amount);
    if (!isFinite(n) || n === 0) return;
    onAdd(label, Math.round(n));
    setLabel(''); setAmount(''); setAdding(false);
  };
  const cancel = () => { setLabel(''); setAmount(''); setAdding(false); };
  const hasAny = extras.length > 0;
  // 沒有任何額外獎金 & 未在新增 → 列印時整段隱藏（no-print），
  // 但螢幕上仍顯示「＋ 新增」入口。
  const wrapClass = 'extras-sec' + (!hasAny && !adding ? ' no-print' : '');
  return (
    <section className={wrapClass}>
      <div className="extras-head">
        <h3>額外獎金 <span className="muted">運營活動加碼、直接匯付新台幣，不套分潤</span></h3>
        {!adding && <button className="btn no-print" onClick={() => setAdding(true)}>＋ 新增額外獎金</button>}
      </div>

      {hasAny && (
        <table className="tbl tbl-extras">
          <thead>
            <tr>
              <th style={{ width: '55%' }}>項目</th>
              <th className="r">金額 TWD</th>
              <th className="no-print" style={{ width: 60 }}></th>
            </tr>
          </thead>
          <tbody>
            {extras.map((x) => (
              <tr key={x.id}>
                <td>{x.label}</td>
                <td className="r num strong payout">{fmtTWD(x.amount)}</td>
                <td className="r no-print"><button className="guild-btn" onClick={() => onRemove(x.id)}>移除</button></td>
              </tr>
            ))}
          </tbody>
          <tfoot>
            <tr>
              <td>額外獎金小計</td>
              <td className="r num strong payout">{fmtTWD(total)}</td>
              <td className="no-print"></td>
            </tr>
          </tfoot>
        </table>
      )}

      {adding && (
        <div className="extras-form no-print">
          <input ref={labelRef} className="extras-input" placeholder="項目名稱（例：中秋活動加碼）"
            value={label} onChange={(e) => setLabel(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && submit()} />
          <div className="extras-amount">
            <span className="muted">NT$</span>
            <input className="num" placeholder="0" value={amount}
              onChange={(e) => setAmount(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') submit(); if (e.key === 'Escape') cancel(); }} />
          </div>
          <button className="btn primary" onClick={submit} disabled={!parseFloat(amount)}>加入</button>
          <button className="btn" onClick={cancel}>取消</button>
        </div>
      )}
    </section>
  );
}

Object.assign(window, { StatementView, ExtraBonusSection });
