/* ============================================================
   details.jsx — detail modals + small shared modal pieces
   Vermogen · Rekeningen · Maandbudget · Agenda-event
   All read through the api.jsx seam, so they light up with real
   data the moment a backend is connected.
   ============================================================ */

/* ---------- date / money helpers ---------- */
function fmtTxnDate(iso) {
  const d = new Date(iso), now = new Date();
  const days = Math.round((new Date(now.getFullYear(), now.getMonth(), now.getDate()) -
    new Date(d.getFullYear(), d.getMonth(), d.getDate())) / 86400000);
  if (days === 0) return "Vandaag";
  if (days === 1) return "Gisteren";
  if (days < 7) return days + " dagen geleden";
  return `${d.getDate()} ${NL_MONTHS[d.getMonth()].slice(0, 3)}`;
}
function fmtSigned(n) {
  const s = Number(n).toLocaleString("nl-NL", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  return (n >= 0 ? "+€" : "−€") + s.replace("-", "");
}

/* ---------- reusable modal shell ---------- */
function ModalShell({ icon, title, sub, onClose, wide, headRight, children }) {
  useEffect(() => {
    const onKey = e => e.key === "Escape" && onClose();
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  const content = (
    <div className="modal-overlay" onClick={onClose}>
      <div className={"modal" + (wide ? " modal-lg" : "")} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div style={{ display: "flex", alignItems: "center", gap: 12, minWidth: 0 }}>
            {icon && <div className="wh-ico" style={{ background: "var(--accent-weak)", color: "var(--accent)", width: 36, height: 36, borderRadius: 11 }}><Icon name={icon} /></div>}
            <div style={{ minWidth: 0 }}>
              <div className="modal-title">{title}</div>
              {sub && <div style={{ fontSize: 12.5, color: "var(--text-3)", fontWeight: 600, marginTop: 1 }}>{sub}</div>}
            </div>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            {headRight}
            <button className="round-btn" onClick={onClose}><Icon name="plus" style={{ transform: "rotate(45deg)" }} /></button>
          </div>
        </div>
        <div className="modal-body">{children}</div>
      </div>
    </div>
  );

  return ReactDOM.createPortal(content, document.body);
}

function ModalLoading({ rows = 4 }) {
  return (
    <div style={{ display: "grid", gap: 12 }}>
      <div className="skel" style={{ height: 120, borderRadius: 14 }} />
      {Array.from({ length: rows }).map((_, i) => <div key={i} className="skel" style={{ height: 46, borderRadius: 12 }} />)}
    </div>
  );
}
function ModalError({ error, onRetry }) {
  return (
    <div style={{ textAlign: "center", padding: "30px 10px" }}>
      <div style={{ fontSize: 14, fontWeight: 700, color: "var(--bad)" }}>Kon gegevens niet laden</div>
      <div style={{ fontSize: 12.5, color: "var(--text-3)", fontWeight: 600, marginTop: 4 }}>{String(error && error.message || error)}</div>
      {onRetry && <button className="btn btn-sm" style={{ marginTop: 14 }} onClick={onRetry}>Opnieuw</button>}
    </div>
  );
}

/* small transaction row reused by accounts + budget */
function TxnRow({ name, sub, amount, color }) {
  const up = amount >= 0;
  return (
    <div className="txn-row">
      <span className="txn-dot" style={{ background: color || (up ? "var(--good)" : "var(--text-3)") }} />
      <div style={{ minWidth: 0, flex: 1 }}>
        <div className="txn-name">{name}</div>
        {sub && <div className="txn-sub">{sub}</div>}
      </div>
      <span className="mono txn-amt" style={{ color: up ? "var(--good)" : "var(--text)" }}>{fmtSigned(amount)}</span>
    </div>
  );
}

/* ============================================================
   VERMOGEN — net-worth detail
   ============================================================ */
function NetWorthDetailModal({ onClose }) {
  const [range, setRange] = useState("1J");
  const { loading, data, error } = useAsync(() => fetchNetWorth(range), [range]);

  return (
    <ModalShell wide icon="chart" title="Vermogen" sub="Opbouw, historie & trend" onClose={onClose}
      headRight={
        <div className="seg">
          {["1M", "6M", "1J"].map(r => <button key={r} className={range === r ? "on" : ""} onClick={() => setRange(r)}>{r}</button>)}
        </div>
      }>
      {error ? <ModalError error={error} /> : (!data) ? <ModalLoading /> : (() => {
        const up = data.delta >= 0;
        const maxB = Math.max(...data.breakdown.map(b => b.value), 1);
        return (
          <div style={{ display: "grid", gap: 22 }}>
            {/* hero + chart */}
            <div className="detail-hero">
              <div>
                <div className="lbl">Totaal netto vermogen</div>
                <div className="big-num" style={{ fontSize: 40, lineHeight: 1.05, marginTop: 4 }}>{fmtEur(data.total)}</div>
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 8 }}>
                  <span className={"chip " + (up ? "up" : "down")}><Icon name={up ? "arrowUp" : "arrowDn"} /> {up ? "+" : ""}{fmtEur(data.delta)}</span>
                  <span style={{ fontSize: 12.5, color: "var(--text-2)", fontWeight: 600 }}>{up ? "+" : ""}{data.pct.toFixed(1)}% in deze periode</span>
                </div>
              </div>
              <div style={{ flex: 1, minWidth: 220, opacity: loading ? 0.5 : 1, transition: "opacity .2s" }}>
                <LineChart data={data.series} height={120} />
              </div>
            </div>

            {/* breakdown */}
            <div>
              <div className="detail-sec-lbl">Opbouw</div>
              <div style={{ display: "grid", gap: 12 }}>
                {data.breakdown.map((b, i) => (
                  <div key={i}>
                    <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 5 }}>
                      <span style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 13.5, fontWeight: 600 }}>
                        <span style={{ width: 9, height: 9, borderRadius: 3, background: b.color }} />{b.label}
                      </span>
                      <span className="mono" style={{ fontSize: 13, fontWeight: 600 }}>{fmtEur(b.value)}
                        <span style={{ color: "var(--text-3)", marginLeft: 7 }}>{Math.round(b.value / data.total * 100)}%</span>
                      </span>
                    </div>
                    <div className="bar"><i style={{ width: `${b.value / maxB * 100}%`, background: b.color }} /></div>
                  </div>
                ))}
              </div>
            </div>

            {/* monthly history */}
            <div>
              <div className="detail-sec-lbl">Maandelijks verloop</div>
              <div className="detail-list">
                {data.history.slice(0, 8).map((h, i) => {
                  const pos = h.delta >= 0;
                  return (
                    <div key={i} className="txn-row">
                      <div style={{ minWidth: 0, flex: 1, textTransform: "capitalize", fontSize: 13.5, fontWeight: 600 }}>{h.month}</div>
                      <span className="mono" style={{ fontSize: 13, color: "var(--text-2)", fontWeight: 600, marginRight: 14 }}>{fmtEur(h.value)}</span>
                      <span className="mono" style={{ fontSize: 12.5, fontWeight: 600, color: i === data.history.length - 1 ? "var(--text-3)" : pos ? "var(--good)" : "var(--bad)", minWidth: 78, textAlign: "right" }}>
                        {i === data.history.length - 1 ? "—" : (pos ? "+" : "−") + fmtEur(Math.abs(h.delta))}
                      </span>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        );
      })()}
    </ModalShell>
  );
}

/* ============================================================
   REKENINGEN — accounts detail with transactions
   ============================================================ */
function AccountsDetailModal({ onClose }) {
  const { data, error } = useAsync(() => fetchAccounts(), []);
  const [openId, setOpenId] = useState(null);
  const total = data ? data.reduce((s, a) => s + a.balance, 0) : 0;

  return (
    <ModalShell wide icon="wallet" title="Rekeningen" sub={data ? fmtEur(total) + " totaal · " + data.length + " rekeningen" : "Laden…"} onClose={onClose}>
      {error ? <ModalError error={error} /> : !data ? <ModalLoading /> : (
        <div style={{ display: "grid", gap: 12 }}>
          {data.map(a => {
            const open = openId === a.id;
            return (
              <div key={a.id} className="acc-block" style={{ borderColor: open ? "var(--border-strong)" : "var(--border)" }}>
                <button className="acc-head" onClick={() => setOpenId(open ? null : a.id)}>
                  <div style={{ width: 40, height: 40, borderRadius: 11, background: a.color, color: "#fff", display: "grid", placeItems: "center", flexShrink: 0 }}>
                    <Icon name={a.icon} width="19" height="19" />
                  </div>
                  <div style={{ minWidth: 0, flex: 1, textAlign: "left" }}>
                    <div style={{ fontSize: 14.5, fontWeight: 700 }}>{a.name}</div>
                    <div style={{ fontSize: 12, color: "var(--text-3)", fontWeight: 600 }}>{a.bank} · {a.transactions.length} transacties</div>
                  </div>
                  <div className="big-num" style={{ fontSize: 16 }}>{fmtEur(a.balance, 2)}</div>
                  <Icon name="chevR" width="16" height="16" style={{ color: "var(--text-3)", transform: open ? "rotate(90deg)" : "none", transition: "transform .2s" }} />
                </button>
                {open && (
                  <div className="detail-list" style={{ borderTop: "1px solid var(--border)", marginTop: 2 }}>
                    {a.transactions.length === 0 && <div style={{ padding: "16px", textAlign: "center", color: "var(--text-3)", fontSize: 13, fontWeight: 600 }}>Geen recente transacties</div>}
                    {a.transactions.map(t => <TxnRow key={t.id} name={t.name} sub={t.category + " · " + fmtTxnDate(t.date)} amount={t.amount} />)}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}
    </ModalShell>
  );
}

/* ============================================================
   MAANDBUDGET — budget detail with per-category transactions
   ============================================================ */
function BudgetDetailModal({ onClose }) {
  const { data, error } = useAsync(() => fetchBudget(0), []);
  const [openCat, setOpenCat] = useState(null);

  return (
    <ModalShell wide icon="wallet" title="Maandbudget" sub={data ? data.monthLabel : "Laden…"} onClose={onClose}>
      {error ? <ModalError error={error} /> : !data ? <ModalLoading /> : (() => {
        const left = data.totalBudget - data.totalSpent;
        const saved = data.income - data.totalSpent;
        return (
          <div style={{ display: "grid", gap: 22 }}>
            <div className="budget-stats">
              <div className="bstat"><div className="lbl">Inkomen</div><div className="big-num" style={{ fontSize: 22 }}>{fmtEur(data.income)}</div></div>
              <div className="bstat"><div className="lbl">Uitgegeven</div><div className="big-num" style={{ fontSize: 22 }}>{fmtEur(data.totalSpent)}</div></div>
              <div className="bstat"><div className="lbl">Nog te besteden</div><div className="big-num" style={{ fontSize: 22, color: "var(--good)" }}>{fmtEur(left)}</div></div>
              <div className="bstat"><div className="lbl">Bespaard</div><div className="big-num" style={{ fontSize: 22, color: "var(--accent)" }}>{fmtEur(saved)}</div></div>
            </div>

            <div>
              <div className="detail-sec-lbl">Categorieën</div>
              <div style={{ display: "grid", gap: 10 }}>
                {data.categories.map((b, i) => {
                  const p = b.spent / b.budget, over = b.spent > b.budget, open = openCat === i;
                  return (
                    <div key={i} className="acc-block" style={{ borderColor: open ? "var(--border-strong)" : "var(--border)" }}>
                      <button className="cat-head" onClick={() => setOpenCat(open ? null : i)}>
                        <span style={{ width: 9, height: 9, borderRadius: 3, background: b.color, flexShrink: 0 }} />
                        <span style={{ flex: 1, textAlign: "left", fontSize: 13.5, fontWeight: 650, minWidth: 0 }}>{b.name}</span>
                        <span className="mono" style={{ fontSize: 12.5, color: over ? "var(--bad)" : "var(--text-2)", fontWeight: 600 }}>
                          {fmtEur(b.spent)} <span style={{ color: "var(--text-3)" }}>/ {fmtEur(b.budget)}</span>
                        </span>
                        <Icon name="chevR" width="15" height="15" style={{ color: "var(--text-3)", transform: open ? "rotate(90deg)" : "none", transition: "transform .2s" }} />
                      </button>
                      <div style={{ padding: "0 14px 12px" }}>
                        <div className="bar"><i style={{ width: `${clamp(p * 100, 3, 100)}%`, background: over ? "var(--bad)" : b.color }} /></div>
                      </div>
                      {open && (
                        <div className="detail-list" style={{ borderTop: "1px solid var(--border)" }}>
                          {b.transactions.length === 0 && <div style={{ padding: "16px", textAlign: "center", color: "var(--text-3)", fontSize: 13, fontWeight: 600 }}>Geen transacties deze maand</div>}
                          {b.transactions.map(t => <TxnRow key={t.id} name={t.name} sub={fmtTxnDate(t.date)} amount={t.amount} color={b.color} />)}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        );
      })()}
    </ModalShell>
  );
}

/* ============================================================
   AGENDA EVENT — detail popover
   ============================================================ */
function EventDetailModal({ event, onClose }) {
  if (!event) return null;
  const s = new Date(event.start), e = new Date(event.end);
  const fmtT = d => `${d.getHours()}:${String(d.getMinutes()).padStart(2, "0")}`;
  const dur = Math.round((e - s) / 60000);
  const durLabel = dur >= 60 ? `${Math.floor(dur / 60)}u${dur % 60 ? " " + (dur % 60) + "m" : ""}` : dur + " min";
  return (
    <ModalShell title={event.title} onClose={onClose}
      sub={`${NL_DAYS_FULL[s.getDay()]} ${s.getDate()} ${NL_MONTHS[s.getMonth()]}`}>
      <div style={{ display: "grid", gap: 14 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span style={{ width: 12, height: 12, borderRadius: 4, background: event.color, flexShrink: 0 }} />
          <span className="chip" style={{ background: "var(--surface-3)" }}>{event.calendarName}</span>
        </div>
        <div className="evt-row"><Icon name="clock" /><div><div className="evt-main">{fmtT(s)} – {fmtT(e)}</div><div className="evt-sub">{durLabel}</div></div></div>
        {event.location && <div className="evt-row"><Icon name="compass" /><div className="evt-main">{event.location}</div></div>}
        {event.attendees && event.attendees.length > 0 && (
          <div className="evt-row"><Icon name="smile" /><div><div className="evt-main">{event.attendees.length} deelnemer{event.attendees.length > 1 ? "s" : ""}</div><div className="evt-sub">{event.attendees.join(", ")}</div></div></div>
        )}
        {event.meetingUrl && (
          <a href={event.meetingUrl} target="_blank" rel="noopener" className="btn btn-accent" style={{ textDecoration: "none", marginTop: 4 }}>
            <Icon name="calendar" /> Deelnemen via Google Meet
          </a>
        )}
      </div>
    </ModalShell>
  );
}

Object.assign(window, {
  ModalShell, ModalLoading, ModalError, TxnRow, fmtTxnDate, fmtSigned,
  NetWorthDetailModal, AccountsDetailModal, BudgetDetailModal, EventDetailModal,
});
