/* global React, Icon, fmtRp, fmtMonthYear, fmtMonthYearOffset, fmtEndOfMonth, useNow */
const { useState: useStateFn, useEffect: useEffectFn } = React;

/* =========================================================
 * Period helpers
 * ========================================================= */
function periodKey(offset = 0, base = new Date()) {
  const d = new Date(base.getFullYear(), base.getMonth() + offset, 1);
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
}

/* =========================================================
 * LABA RUGI (P&L) — derived from posted journal entries
 * ========================================================= */
function ProfitLossPage() {
  const now = useNow(60_000);
  const thisMonth = fmtMonthYear(now);
  const lastMonth = fmtMonthYearOffset(-1, now);
  const [periodSel, setPeriodSel] = useStateFn('this');
  const [data, setData] = useStateFn(null);
  const [prev, setPrev] = useStateFn(null);
  const [loading, setLoading] = useStateFn(true);

  const offsetForSel = (sel) => sel === 'last' ? -1 : sel === 'q' ? 0 : sel === 'ytd' ? 0 : 0;
  const periodLabel = periodSel === 'this' ? thisMonth
    : periodSel === 'last' ? lastMonth
    : periodSel === 'q' ? `Q${Math.floor(now.getMonth() / 3) + 1} ${now.getFullYear()}`
    : `YTD ${now.getFullYear()}`;

  const load = async () => {
    setLoading(true);
    try {
      const periodStr = periodKey(periodSel === 'last' ? -1 : 0, now);
      const periodPrev = periodKey(periodSel === 'last' ? -2 : -1, now);
      const [r, rPrev] = await Promise.all([
        window.Api.get(`/api/finance/pl?period=${periodStr}`),
        window.Api.get(`/api/finance/pl?period=${periodPrev}`),
      ]);
      setData(r.data);
      setPrev(rPrev.data);
    } finally { setLoading(false); }
  };
  useEffectFn(() => { load(); /* eslint-disable-next-line */ }, [periodSel]);

  if (loading || !data) {
    return (
      <div className="page">
        <div className="page-head">
          <div><h1 className="page-title">Laporan Laba Rugi</h1></div>
        </div>
        <div className="card" style={{ padding:40, textAlign:'center', color:'var(--ink-500)' }}>Memuat dari journal…</div>
      </div>
    );
  }

  const noData = data.revenue.length === 0 && data.cogs.length === 0 && data.opex.length === 0;

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Laporan Laba Rugi</h1>
          <p className="page-sub">Income Statement · Periode {periodLabel} · derived dari posted journal entries</p>
        </div>
        <div className="page-actions">
          <select className="btn btn-secondary" value={periodSel} onChange={e => setPeriodSel(e.target.value)}>
            <option value="this">{thisMonth}</option>
            <option value="last">{lastMonth}</option>
            <option value="q">Kuartal Berjalan</option>
            <option value="ytd">YTD {now.getFullYear()}</option>
          </select>
          <button className="btn btn-secondary"><Icon.download/> Ekspor PDF</button>
        </div>
      </div>

      {noData && (
        <div className="card" style={{ padding:24, textAlign:'center', color:'var(--ink-500)' }}>
          Tidak ada transaksi posted di periode ini. Buat jurnal manual atau kirim pesanan untuk lihat laporan.
        </div>
      )}

      {!noData && (
        <>
          <div className="grid-4" style={{ marginBottom:18 }}>
            <Kpi label="Pendapatan Bersih" value={fmtRp(data.netRevenue)} sub="setelah retur & diskon" tone="brand"/>
            <Kpi label="Laba Kotor" value={fmtRp(data.grossProfit)} sub={`Margin ${marginPct(data.grossProfit, data.netRevenue)}%`} tone="blue"/>
            <Kpi label="Laba Operasi" value={fmtRp(data.operatingProfit)} sub={`Margin ${marginPct(data.operatingProfit, data.netRevenue)}%`} tone="amber"/>
            <Kpi label="Laba Bersih" value={fmtRp(data.netProfit)} sub={`Margin ${marginPct(data.netProfit, data.netRevenue)}%`} tone="green"/>
          </div>

          <div className="card">
            <table className="table table-finance">
              <thead>
                <tr>
                  <th style={{ width:'45%' }}>Akun</th>
                  <th style={{ textAlign:'right' }}>Periode Ini</th>
                  <th style={{ textAlign:'right' }}>Periode Sebelumnya</th>
                  <th style={{ textAlign:'right' }}>% Pendapatan</th>
                </tr>
              </thead>
              <tbody>
                {data.revenue.length > 0 && <SectionHeader label="PENDAPATAN"/>}
                {data.revenue.map((r, idx) => (
                  <Line key={idx} {...r} prev={findPrev(prev?.revenue, r.code)} ratio={r.amount / data.netRevenue || 0}/>
                ))}
                {data.revenue.length > 0 && <Subtotal label="Total Pendapatan Kotor" amt={data.grossRevenue} prev={prev?.grossRevenue}/>}

                {data.deductions.length > 0 && (
                  <>
                    <SectionHeader label="POTONGAN"/>
                    {data.deductions.map((r, idx) => (
                      <Line key={idx} {...r} prev={findPrev(prev?.deductions, r.code)} ratio={r.amount / data.netRevenue || 0} negative/>
                    ))}
                    <Subtotal label="Pendapatan Bersih" amt={data.netRevenue} prev={prev?.netRevenue} highlight/>
                  </>
                )}

                {data.cogs.length > 0 && (
                  <>
                    <SectionHeader label="HARGA POKOK PENJUALAN (HPP)"/>
                    {data.cogs.map((r, idx) => (
                      <Line key={idx} {...r} prev={findPrev(prev?.cogs, r.code)} ratio={r.amount / data.netRevenue || 0} negative/>
                    ))}
                    <Subtotal label="Laba Kotor (Gross Profit)" amt={data.grossProfit} prev={prev?.grossProfit} highlight/>
                  </>
                )}

                {data.opex.length > 0 && (
                  <>
                    <SectionHeader label="BIAYA OPERASIONAL"/>
                    {data.opex.map((r, idx) => (
                      <Line key={idx} {...r} prev={findPrev(prev?.opex, r.code)} ratio={r.amount / data.netRevenue || 0} negative/>
                    ))}
                    <Subtotal label="Laba Operasi (EBIT)" amt={data.operatingProfit} prev={prev?.operatingProfit} highlight/>
                  </>
                )}

                {data.tax.length > 0 && (
                  <>
                    <SectionHeader label="PAJAK"/>
                    {data.tax.map((r, idx) => (
                      <Line key={idx} {...r} prev={findPrev(prev?.tax, r.code)} ratio={r.amount / data.netRevenue || 0} negative/>
                    ))}
                  </>
                )}

                <Subtotal label="LABA BERSIH" amt={data.netProfit} prev={prev?.netProfit} highlight final/>
              </tbody>
            </table>
          </div>
        </>
      )}
    </div>
  );
}

function findPrev(arr, code) {
  if (!arr) return 0;
  const found = arr.find((r) => r.code === code);
  return found?.amount ?? 0;
}
function marginPct(num, denom) {
  if (!denom) return '0.0';
  return ((num / denom) * 100).toFixed(1);
}

/* =========================================================
 * NERACA (Balance Sheet) — derived from posted journal entries
 * ========================================================= */
function BalanceSheetPage() {
  const now = useNow(60_000);
  const thisEom = fmtEndOfMonth(0, now);
  const lastEom = fmtEndOfMonth(-1, now);
  const [periodSel, setPeriodSel] = useStateFn('this');
  const [data, setData] = useStateFn(null);
  const [loading, setLoading] = useStateFn(true);

  const eomISO = (offset) => {
    const d = new Date(now.getFullYear(), now.getMonth() + offset + 1, 0);
    return d.toISOString().slice(0, 10);
  };

  useEffectFn(() => {
    setLoading(true);
    const asOf = periodSel === 'this' ? eomISO(0)
      : periodSel === 'last' ? eomISO(-1)
      : `${now.getFullYear() - 1}-12-31`;
    window.Api.get(`/api/finance/balance?asOf=${asOf}`).then(r => {
      setData(r.data);
      setLoading(false);
    });
    /* eslint-disable-next-line */
  }, [periodSel]);

  if (loading || !data) {
    return (
      <div className="page">
        <div className="page-head"><div><h1 className="page-title">Neraca</h1></div></div>
        <div className="card" style={{ padding:40, textAlign:'center', color:'var(--ink-500)' }}>Memuat…</div>
      </div>
    );
  }

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Neraca</h1>
          <p className="page-sub">Balance Sheet · per {data.asOf} · derived dari posted journal entries</p>
        </div>
        <div className="page-actions">
          <select className="btn btn-secondary" value={periodSel} onChange={e=>setPeriodSel(e.target.value)}>
            <option value="this">{thisEom}</option>
            <option value="last">{lastEom}</option>
            <option value="ye">31 Desember {now.getFullYear() - 1}</option>
          </select>
          <button className="btn btn-secondary"><Icon.download/> Ekspor</button>
        </div>
      </div>

      <div className="grid-3" style={{ marginBottom:18 }}>
        <Kpi label="Total Aset" value={fmtRp(data.totalAssets)} tone="brand"/>
        <Kpi label="Total Liabilitas" value={fmtRp(data.liabilities.total)}
          sub={data.totalAssets ? `${((data.liabilities.total / data.totalAssets) * 100).toFixed(0)}% dari aset` : ''} tone="amber"/>
        <Kpi label="Total Ekuitas" value={fmtRp(data.equity.total)}
          sub={data.totalAssets ? `${((data.equity.total / data.totalAssets) * 100).toFixed(0)}% dari aset` : ''} tone="green"/>
      </div>

      <div className="grid-2">
        {/* ASET */}
        <div className="card">
          <table className="table table-finance">
            <thead><tr><th colSpan="2" style={{ background:'var(--brand-50)', color:'var(--brand-700)' }}>ASET</th></tr></thead>
            <tbody>
              {data.assets.current.length > 0 && <SectionHeader label="ASET LANCAR"/>}
              {data.assets.current.map((l, idx) => <BLine key={idx} name={l.name} code={l.code} amt={l.amount}/>)}
              {data.assets.current.length > 0 && <Subtotal label="Total Aset Lancar" amt={data.assets.totalCurrent}/>}

              {data.assets.fixed.length > 0 && <SectionHeader label="ASET TETAP"/>}
              {data.assets.fixed.map((l, idx) => <BLine key={idx} name={l.name} code={l.code} amt={l.amount} negative={l.amount < 0}/>)}
              {data.assets.fixed.length > 0 && <Subtotal label="Total Aset Tetap" amt={data.assets.totalFixed}/>}

              {data.assets.current.length === 0 && data.assets.fixed.length === 0 && (
                <tr><td colSpan="2" style={{ padding:20, textAlign:'center', color:'var(--ink-500)' }}>Belum ada saldo aset.</td></tr>
              )}
              <Subtotal label="TOTAL ASET" amt={data.totalAssets} highlight final/>
            </tbody>
          </table>
        </div>

        {/* LIAB + EQUITY */}
        <div className="card">
          <table className="table table-finance">
            <thead><tr><th colSpan="2" style={{ background:'var(--brand-50)', color:'var(--brand-700)' }}>LIABILITAS &amp; EKUITAS</th></tr></thead>
            <tbody>
              {data.liabilities.current.length > 0 && <SectionHeader label="LIABILITAS LANCAR"/>}
              {data.liabilities.current.map((l, idx) => <BLine key={idx} name={l.name} code={l.code} amt={l.amount}/>)}
              {data.liabilities.current.length > 0 && <Subtotal label="Total Liabilitas Lancar" amt={data.liabilities.totalCurrent}/>}

              {data.liabilities.longTerm.length > 0 && <SectionHeader label="LIABILITAS JANGKA PANJANG"/>}
              {data.liabilities.longTerm.map((l, idx) => <BLine key={idx} name={l.name} code={l.code} amt={l.amount}/>)}
              {data.liabilities.total > 0 && <Subtotal label="Total Liabilitas" amt={data.liabilities.total}/>}

              <SectionHeader label="EKUITAS"/>
              {data.equity.lines.length === 0 && (
                <tr><td colSpan="2" style={{ padding:14, fontSize:12, color:'var(--ink-500)', paddingLeft:28 }}>Belum ada saldo ekuitas.</td></tr>
              )}
              {data.equity.lines.map((l, idx) => <BLine key={idx} name={l.name} code={l.code} amt={l.amount} negative={l.amount < 0}/>)}
              <Subtotal label="Total Ekuitas" amt={data.equity.total}/>

              <Subtotal label="TOTAL LIABILITAS &amp; EKUITAS" amt={data.totalLiabEquity} highlight final/>
            </tbody>
          </table>
        </div>
      </div>

      <div style={{
        marginTop:14, padding:'14px 18px', borderRadius:12,
        background: data.balanced ? 'var(--green-bg, #ecfdf3)' : 'var(--amber-bg, #fef9c3)',
        border:'1px solid ' + (data.balanced ? 'var(--green, #1c8e5a)' : 'var(--amber, #c47a06)'),
        display:'flex', alignItems:'center', gap:12, fontSize:13
      }}>
        <span style={{
          width:28, height:28, borderRadius:8,
          background: data.balanced ? 'var(--green)' : 'var(--amber)',
          color:'white', display:'grid', placeItems:'center', fontWeight:700, flexShrink:0,
        }}>{data.balanced ? '✓' : '!'}</span>
        <div>
          {data.balanced ? (
            <><strong>Neraca seimbang.</strong> <span style={{ color:'var(--ink-500)' }}>Aset = Liabilitas + Ekuitas = {fmtRp(data.totalAssets)}</span></>
          ) : (
            <>
              <strong>Selisih {fmtRp(data.difference)}.</strong>{' '}
              <span style={{ color:'var(--ink-500)' }}>Aset {fmtRp(data.totalAssets)} ≠ Liabilitas+Ekuitas {fmtRp(data.totalLiabEquity)}.</span>
              {data.assets.current.some(l => l.amount < 0) && <div style={{ marginTop:4, fontSize:12 }}>
                💡 Persediaan Produk negatif menandakan stok sudah keluar tapi opening balance belum di-input. Bikin manual journal: <strong>Dr 1160 Persediaan Produk</strong>, <strong>Cr 3110 Modal Pemilik</strong> sebesar nilai stok awal Anda.
              </div>}
            </>
          )}
        </div>
      </div>
    </div>
  );
}

/* =========================================================
 * ARUS KAS — derived from posted journal entries
 * ========================================================= */
function CashFlowPage() {
  const now = useNow(60_000);
  const thisMonth = fmtMonthYear(now);
  const lastMonth = fmtMonthYearOffset(-1, now);
  const [periodSel, setPeriodSel] = useStateFn('this');
  const [data, setData] = useStateFn(null);
  const [loading, setLoading] = useStateFn(true);

  useEffectFn(() => {
    setLoading(true);
    const periodStr = periodKey(periodSel === 'last' ? -1 : 0, now);
    window.Api.get(`/api/finance/cashflow?period=${periodStr}`).then(r => {
      setData(r.data);
      setLoading(false);
    });
    /* eslint-disable-next-line */
  }, [periodSel]);

  if (loading || !data) {
    return (
      <div className="page">
        <div className="page-head"><div><h1 className="page-title">Laporan Arus Kas</h1></div></div>
        <div className="card" style={{ padding:40, textAlign:'center', color:'var(--ink-500)' }}>Memuat…</div>
      </div>
    );
  }

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Laporan Arus Kas</h1>
          <p className="page-sub">Cash Flow Statement · Periode {periodSel === 'this' ? thisMonth : lastMonth} · derived dari journal</p>
        </div>
        <div className="page-actions">
          <select className="btn btn-secondary" value={periodSel} onChange={e=>setPeriodSel(e.target.value)}>
            <option value="this">{thisMonth}</option>
            <option value="last">{lastMonth}</option>
          </select>
          <button className="btn btn-secondary"><Icon.download/> Ekspor</button>
        </div>
      </div>

      <div className="grid-4" style={{ marginBottom:18 }}>
        <Kpi label="Saldo Awal" value={fmtRp(data.openingBalance)} sub={data.period.from} tone="blue"/>
        <Kpi label="Kas Masuk" value={fmtRp(positiveSum(data))} sub="Total inflow" tone="green"/>
        <Kpi label="Kas Keluar" value={fmtRp(negativeSum(data))} sub="Total outflow" tone="amber"/>
        <Kpi label="Saldo Akhir" value={fmtRp(data.closingBalance)} sub={`per ${data.period.to}`} tone="brand"/>
      </div>

      <div className="grid-2">
        <div className="card">
          <table className="table table-finance">
            <thead>
              <tr><th colSpan="2" style={{ background:'var(--brand-50)', color:'var(--brand-700)' }}>ARUS KAS OPERASI</th></tr>
            </thead>
            <tbody>
              {data.operating.items.length === 0 && (
                <tr><td colSpan="2" style={{ padding:20, textAlign:'center', color:'var(--ink-500)' }}>Belum ada arus kas operasi.</td></tr>
              )}
              {data.operating.items.map((l, idx) => (
                <BLine key={idx} name={l.description} code={l.accountCode} amt={l.amount} negative={l.amount < 0}/>
              ))}
              <Subtotal label="Arus Kas Bersih dari Operasi" amt={data.operating.net} highlight/>
            </tbody>
          </table>
        </div>

        <div className="card">
          <table className="table table-finance">
            <thead>
              <tr><th colSpan="2" style={{ background:'var(--brand-50)', color:'var(--brand-700)' }}>INVESTASI &amp; PENDANAAN</th></tr>
            </thead>
            <tbody>
              <SectionHeader label="ARUS KAS INVESTASI"/>
              {data.investing.items.length === 0 && (
                <tr><td colSpan="2" style={{ padding:14, fontSize:12, color:'var(--ink-500)', paddingLeft:28 }}>Belum ada arus kas investasi.</td></tr>
              )}
              {data.investing.items.map((l, idx) => (
                <BLine key={idx} name={l.description} code={l.accountCode} amt={l.amount} negative={l.amount < 0}/>
              ))}
              {data.investing.items.length > 0 && <Subtotal label="Arus Kas dari Investasi" amt={data.investing.net} negative={data.investing.net < 0}/>}

              <SectionHeader label="ARUS KAS PENDANAAN"/>
              {data.financing.items.length === 0 && (
                <tr><td colSpan="2" style={{ padding:14, fontSize:12, color:'var(--ink-500)', paddingLeft:28 }}>Belum ada arus kas pendanaan.</td></tr>
              )}
              {data.financing.items.map((l, idx) => (
                <BLine key={idx} name={l.description} code={l.accountCode} amt={l.amount} negative={l.amount < 0}/>
              ))}
              {data.financing.items.length > 0 && <Subtotal label="Arus Kas dari Pendanaan" amt={data.financing.net} negative={data.financing.net < 0}/>}

              <SectionHeader label="REKAPITULASI"/>
              <BLine name="Saldo Awal Periode" amt={data.openingBalance}/>
              <BLine name="Kenaikan/Penurunan Bersih Kas" amt={data.netChange} negative={data.netChange < 0}/>
              <Subtotal label="Saldo Akhir Periode" amt={data.closingBalance} highlight final/>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

function positiveSum(data) {
  const all = [...data.operating.items, ...data.investing.items, ...data.financing.items];
  return all.filter(l => l.amount > 0).reduce((s, l) => s + l.amount, 0);
}
function negativeSum(data) {
  const all = [...data.operating.items, ...data.investing.items, ...data.financing.items];
  return -all.filter(l => l.amount < 0).reduce((s, l) => s + l.amount, 0);
}

/* =========================================================
 * Shared
 * ========================================================= */
function Kpi({ label, value, sub, tone='brand' }) {
  const colors = { brand:'var(--brand-500)', blue:'var(--blue)', amber:'var(--amber)', green:'var(--green)' };
  return (
    <div className="metric">
      <div className="metric-label">{label}</div>
      <div className="metric-value" style={{ fontFeatureSettings:'"tnum"' }}>{value}</div>
      {sub && <div style={{ fontSize:12.5, color:colors[tone], fontWeight:600, marginTop:4 }}>{sub}</div>}
    </div>
  );
}
function SectionHeader({ label }) {
  return (
    <tr>
      <td colSpan="4" style={{
        fontSize:11, fontWeight:700, textTransform:'uppercase',
        letterSpacing:'.06em', color:'var(--ink-600)',
        background:'var(--surface-2)', padding:'10px 16px'
      }}>{label}</td>
    </tr>
  );
}
function Line({ name, code, amount, prev, ratio, negative }) {
  return (
    <tr>
      <td style={{ paddingLeft:28 }}>
        {code && <span className="mono" style={{ marginRight:6, opacity:.5, fontSize:12 }}>{code}</span>}
        {name}
      </td>
      <td style={{ textAlign:'right', fontFeatureSettings:'"tnum"', color: negative ? 'var(--ink-700)' : 'inherit' }}>{fmtRp(amount)}</td>
      <td style={{ textAlign:'right', fontFeatureSettings:'"tnum"', color:'var(--ink-500)', fontSize:13 }}>{fmtRp(Math.round(prev || 0))}</td>
      <td style={{ textAlign:'right', color:'var(--ink-500)', fontSize:13 }}>{(Math.abs(ratio || 0) * 100).toFixed(1)}%</td>
    </tr>
  );
}
function BLine({ name, code, amt, negative }) {
  return (
    <tr>
      <td style={{ paddingLeft:28 }}>
        {code && <span className="mono" style={{ marginRight:6, opacity:.5, fontSize:12 }}>{code}</span>}
        {name}
      </td>
      <td style={{ textAlign:'right', fontFeatureSettings:'"tnum"', color: negative ? 'var(--ink-600)' : 'inherit' }}>{fmtRp(amt)}</td>
    </tr>
  );
}
function Subtotal({ label, amt, prev, highlight, final, negative }) {
  return (
    <tr style={{
      background: highlight ? (final ? 'var(--brand-50)' : 'var(--surface-2)') : 'transparent',
      borderTop: highlight ? '1.5px solid var(--brand-300)' : '1px solid var(--border)',
      borderBottom: final ? '2px double var(--brand-500)' : 'none'
    }}>
      <td style={{ fontWeight:700, paddingLeft:16 }}>{label}</td>
      <td style={{
        textAlign:'right', fontWeight:final ? 800 : 700, fontFeatureSettings:'"tnum"',
        fontSize: final ? 16 : 14,
        color: final ? 'var(--brand-600)' : (negative ? 'var(--ink-700)' : 'inherit')
      }}>{fmtRp(amt)}</td>
      {prev !== undefined && (
        <>
          <td style={{ textAlign:'right', fontFeatureSettings:'"tnum"', fontWeight:600, color:'var(--ink-500)' }}>{fmtRp(Math.round(prev || 0))}</td>
          <td/>
        </>
      )}
    </tr>
  );
}

window.ProfitLossPage = ProfitLossPage;
window.BalanceSheetPage = BalanceSheetPage;
window.CashFlowPage = CashFlowPage;
