/* global React, CRYPTOLIVE_DATA, Coin, fmtPrice, fmtPct, fmtUSD, fmtKRW, useT */

// Portfolio holdings are fetched from BFF at runtime via /api/v1/portfolio.
// No hardcoded mock data — positions come from source-backed DB records.
const BFF_BASE = '';

function DonutChart({ items, size = 180 }) {
  const total = items.reduce((s, i) => s + i.value, 0);
  const cx = size / 2, cy = size / 2, r = size / 2 - 14, sw = 24;
  let acc = 0;
  const segments = items.map((it) => {
    const start = acc, frac = it.value / total;
    acc += frac;
    const a1 = start * Math.PI * 2 - Math.PI / 2;
    const a2 = acc * Math.PI * 2 - Math.PI / 2;
    const large = frac > 0.5 ? 1 : 0;
    const x1 = cx + r * Math.cos(a1), y1 = cy + r * Math.sin(a1);
    const x2 = cx + r * Math.cos(a2), y2 = cy + r * Math.sin(a2);
    const d = `M${x1},${y1} A${r},${r} 0 ${large} 1 ${x2},${y2}`;
    return { d, color: it.color, label: it.label, frac };
  });
  return (
    <svg viewBox={`0 0 ${size} ${size}`} style={{ width: size, height: size }}>
      <circle cx={cx} cy={cy} r={r} fill="none" stroke="var(--bg-muted)" strokeWidth={sw} />
      {segments.map((s, i) => (
        <path key={i} d={s.d} fill="none" stroke={s.color} strokeWidth={sw} strokeLinecap="butt" />
      ))}
    </svg>
  );
}

function PortfolioMiniChart({ totalValue, totalCost }) {
  const t = useT();
  const [range, setRange] = React.useState('1M');
  const ranges = ['1D', '1W', '1M', '3M', '1Y'];
  const n = { '1D': 24, '1W': 28, '1M': 30, '3M': 30, '1Y': 36 }[range];
  const series = React.useMemo(() => {
    const arr = [];
    let p = totalCost;
    for (let i = 0; i < n; i++) {
      const drift = (totalValue - p) / (n - i || 1);
      p = p + drift + (Math.sin(i * 0.7 + n) + Math.cos(i * 1.3)) * totalValue * 0.006;
      arr.push(p);
    }
    arr[arr.length - 1] = totalValue;
    return arr;
  }, [range, totalValue, totalCost, n]);
  const min = Math.min(...series), max = Math.max(...series), span = max - min || 1;
  const w = 600, h = 140;
  const stepX = w / (series.length - 1);
  const pts = series.map((v, i) => [i * stepX, h - ((v - min) / span) * (h - 24) - 12]);
  const d = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(' ');
  const dFill = d + ` L${w},${h} L0,${h} Z`;
  const periodPnl = series[series.length - 1] - series[0];
  const periodPct = (periodPnl / series[0]) * 100;
  const up = periodPnl >= 0;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 200 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 8, gap: 12 }}>
        <div>
          <div className="t-meta">{t('periodPnl')}</div>
          <div className={`t-h3 t-num ${up ? 'c-up' : 'c-down'}`} style={{ marginTop: 2 }}>
            {up ? '+' : ''}${periodPnl.toFixed(0)} <span style={{ fontSize: 13, fontWeight: 600 }}>({up ? '+' : ''}{periodPct.toFixed(2)}%)</span>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 4 }}>
          {ranges.map(r => (
            <button key={r} onClick={() => setRange(r)}
              className={`chip ${range === r ? 'chip--active' : ''}`}
              style={{ height: 26, padding: '0 10px', fontSize: 12 }}>{r}</button>
          ))}
        </div>
      </div>
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ width: '100%', flex: 1, minHeight: 110, display: 'block' }}>
        <defs>
          <linearGradient id="pfg" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={up ? 'var(--up)' : 'var(--down)'} stopOpacity="0.22" />
            <stop offset="100%" stopColor={up ? 'var(--up)' : 'var(--down)'} stopOpacity="0" />
          </linearGradient>
        </defs>
        <path d={dFill} fill="url(#pfg)" />
        <path d={d} fill="none" stroke={up ? 'var(--up)' : 'var(--down)'} strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
      </svg>
    </div>
  );
}

function AddPositionModal({ onClose, onAdd }) {
  const t = useT();
  const [step, setStep] = React.useState('pick');
  const [picked, setPicked] = React.useState(null);
  const [qty, setQty] = React.useState('');
  const [cost, setCost] = React.useState('');
  const [query, setQuery] = React.useState('');
  const [buyDate, setBuyDate] = React.useState(() => new Date().toISOString().slice(0, 10));
  const [venue, setVenue] = React.useState('');
  const list = CRYPTOLIVE_DATA.assets().filter(a =>
    !query || a.symbol.toLowerCase().includes(query.toLowerCase()) || a.name.toLowerCase().includes(query.toLowerCase())
  );
  React.useEffect(() => {
    const onKey = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);
  const submit = () => {
    if (!picked || !qty || !cost || !venue) return;
    onAdd({ id: picked.id, qty: parseFloat(qty), cost: parseFloat(cost), buyDate, venue });
    onClose();
  };
  const today = new Date().toISOString().slice(0, 10);
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 520 }}>
        <div style={{ padding: '20px 24px', borderBottom: '1px solid var(--line-soft)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ fontWeight: 800, fontSize: 18, letterSpacing: '-0.01em' }}>
              {step === 'pick' ? t('addHoldingTitle') : t('buyInfoTitle', picked?.symbol)}
            </div>
            <div className="t-meta" style={{ marginTop: 2 }}>
              {step === 'pick' ? t('addHoldingPickHint') : t('addHoldingInputHint')}
            </div>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label={t('closeBtn')}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><path d="M6 6l12 12M6 18L18 6"/></svg>
          </button>
        </div>
        {step === 'pick' && (
          <div>
            <div style={{ padding: '12px 24px' }}>
              <input className="input" placeholder={t('searchSymbol')} value={query} onChange={(e) => setQuery(e.target.value)} autoFocus />
            </div>
            <div style={{ maxHeight: 380, overflow: 'auto', padding: '0 24px 8px' }}>
              {list.map(a => (
                <div key={a.id} className="row" onClick={() => { setPicked(a); setCost(a.tokenPrice.toFixed(2)); setVenue(a.venues?.[0]?.name || ''); setStep('input'); }}>
                  <Coin id={a.id} symbol={a.symbol} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 700 }}>{a.symbol}</div>
                    <div className="t-meta">{a.name} · {a.class}</div>
                  </div>
                  <div className="t-num" style={{ fontWeight: 600 }}>${fmtPrice(a.tokenPrice)}</div>
                </div>
              ))}
              {list.length === 0 && <div className="t-meta" style={{ padding: '32px 0', textAlign: 'center' }}>{t('noResults')}</div>}
            </div>
          </div>
        )}
        {step === 'input' && picked && (
          <div style={{ padding: '20px 24px 24px' }}>
            <div className="row" style={{ pointerEvents: 'none', padding: '12px 0', borderBottom: '1px solid var(--line-soft)', marginBottom: 16 }}>
              <Coin id={picked.id} symbol={picked.symbol} />
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 700 }}>{picked.symbol}</div>
                <div className="t-meta">{t('currentPrice')} ${fmtPrice(picked.tokenPrice)}</div>
              </div>
            </div>
            <div style={{ marginBottom: 12 }}>
              <div className="t-meta" style={{ marginBottom: 6 }}>{t('qtyHeld')}</div>
              <input className="input" type="number" placeholder="0" value={qty} onChange={(e) => setQty(e.target.value)} autoFocus />
            </div>
            <div style={{ marginBottom: 12 }}>
              <div className="t-meta" style={{ marginBottom: 6 }}>{t('avgCost')}</div>
              <input className="input" type="number" placeholder="0.00" value={cost} onChange={(e) => setCost(e.target.value)} />
            </div>
            <div style={{ marginBottom: 12 }}>
              <div className="t-meta" style={{ marginBottom: 6 }}>{t('buyDate')}</div>
              <input className="input" type="date" max={today} value={buyDate} onChange={(e) => setBuyDate(e.target.value)} />
            </div>
            <div style={{ marginBottom: 16 }}>
              <div className="t-meta" style={{ marginBottom: 6 }}>{t('buyVenue', picked.venues?.length || 0)}</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                {(picked.venues || []).map(v => {
                  const active = venue === v.name;
                  return (
                    <button
                      key={v.name}
                      type="button"
                      onClick={() => setVenue(v.name)}
                      className="chip"
                      style={{
                        padding: '8px 12px',
                        borderRadius: 10,
                        border: `1px solid ${active ? 'var(--blue)' : 'var(--line)'}`,
                        background: active ? 'var(--blue-soft)' : 'var(--bg-card)',
                        color: active ? 'var(--blue-strong, var(--blue))' : 'var(--fg-1)',
                        fontWeight: 600,
                        fontSize: 13,
                        display: 'flex',
                        alignItems: 'center',
                        gap: 6,
                        cursor: 'pointer'
                      }}
                    >
                      <span>{v.name}</span>
                      <span className="t-meta" style={{ fontWeight: 500, color: active ? 'inherit' : 'var(--fg-3)' }}>{v.share}%</span>
                    </button>
                  );
                })}
              </div>
            </div>
            {qty && cost && (
              <div style={{ padding: 12, borderRadius: 12, background: 'var(--bg-muted)', marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
                <span className="t-meta">{t('totalCost')}</span>
                <span className="t-num" style={{ fontWeight: 700 }}>${(parseFloat(qty) * parseFloat(cost)).toFixed(2)}</span>
              </div>
            )}
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn btn--lg" style={{ flex: 1 }} onClick={() => setStep('pick')}>{t('prev')}</button>
              <button className="btn btn--primary btn--lg" style={{ flex: 2 }} onClick={submit} disabled={!qty || !cost || !venue}>{t('addToPortfolio')}</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function PortfolioScreen({ goto }) {
  const t = useT();
  const [holdings, setHoldings] = React.useState([]);
  const [portfolioLoading, setPortfolioLoading] = React.useState(true);
  const [showAdd, setShowAdd] = React.useState(false);
  const [toast, setToast] = React.useState(null);

  // Fetch live portfolio from BFF on mount
  React.useEffect(() => {
    let cancelled = false;
    setPortfolioLoading(true);
    fetch(BFF_BASE + '/api/v1/portfolio')
      .then((res) => res.json())
      .then((data) => {
        if (cancelled) return;
        const positions = (data.holdings ?? []).map((p) => ({
          id: p.assetKey ?? p.symbol?.toLowerCase().replace(/[^a-z0-9]/g, ''),
          qty: Number(p.quantity ?? 0),
          cost: Number(p.averageCost ?? 0),
          buyDate: p.buyDate ?? new Date().toISOString().slice(0, 10),
          venue: p.venue ?? 'BFF',
        }));
        setHoldings(positions);
        setPortfolioLoading(false);
      })
      .catch(() => {
        if (!cancelled) {
          setHoldings([]);
          setPortfolioLoading(false);
        }
      });
    return () => { cancelled = true; };
  }, []);

  const rows = holdings.map(h => {
    const a = CRYPTOLIVE_DATA.assets().find(x => x.id === h.id);
    if (!a) return null;
    const value = h.qty * a.tokenPrice;
    const costBasis = h.qty * h.cost;
    const pnl = value - costBasis;
    const pnlPct = costBasis > 0 ? (pnl / costBasis) * 100 : 0;
    return { ...h, asset: a, value, costBasis, pnl, pnlPct };
  }).filter(Boolean);

  if (portfolioLoading) {
    return (
      <div className="container page" data-screen-label="Portfolio">
        <div style={{ marginBottom: 20 }}>
          <div className="t-h1">{t('myPortfolio')}</div>
          <div className="t-meta" style={{ marginTop: 4 }}>{t('loading')}</div>
        </div>
        <div className="card" style={{ padding: 40, textAlign: 'center' }}>
          <div className="t-meta">{t('loadingPortfolio')}</div>
        </div>
      </div>
    );
  }

  const totalValue = rows.reduce((s, r) => s + r.value, 0);
  const totalCost = rows.reduce((s, r) => s + r.costBasis, 0);
  const totalPnl = totalValue - totalCost;
  const totalPnlPct = totalCost > 0 ? (totalPnl / totalCost) * 100 : 0;
  const dayChange = rows.reduce((s, r) => s + r.value * (r.asset.change24h / 100), 0);

  // Allocation by class
  const byClass = {};
  rows.forEach(r => { byClass[r.asset.class] = (byClass[r.asset.class] || 0) + r.value; });
  const CLASS_COLORS = { '주식형': '#3182f6', 'ETF형': '#6a5cf2', '채권형': '#0f766e', '수익형': '#f4b731', '원자재형': '#c69a3a' };
  const allocation = Object.entries(byClass).map(([k, v]) => ({ label: k, value: v, color: CLASS_COLORS[k] }));

  const riskScore = totalValue > 0 ? Math.round(rows.reduce((s, r) => s + r.asset.riskScore * (r.value / totalValue), 0)) : 0;

  return (
    <div className="container page" data-screen-label="Portfolio">
      <div style={{ marginBottom: 20 }}>
        <div className="t-h1">{t('myPortfolio')}</div>
        <div className="t-meta" style={{ marginTop: 4 }}>
          {rows.length > 0 ? t('portfolioSub', rows.length) : t('noHoldings')}
        </div>
      </div>

      {rows.length === 0 && (
        <div className="card" style={{ padding: 40, textAlign: 'center', marginBottom: 16 }}>
          <div className="t-h3">{t('noPositions')}</div>
          <div className="t-meta" style={{ marginTop: 8 }}>{t('addFirstPosition')}</div>
          <button className="btn btn--primary btn--sm" style={{ marginTop: 16 }} onClick={() => setShowAdd(true)}>
            {t('addHolding')}
          </button>
        </div>
      )}

      {/* Hero */}
      <div className="card card-pad-lg pf-hero" style={{ marginBottom: 16, background: 'var(--hero-grad)' }}>
        <div className="pf-hero-left">
          <div className="t-meta" style={{ marginBottom: 6 }}>{t('totalValue')}</div>
          <div className="t-display t-num">${totalValue.toLocaleString('en-US', { maximumFractionDigits: 0 })}</div>
          <div className="t-meta" style={{ marginTop: 2 }}>≈ {fmtKRW(totalValue)}</div>
          <div style={{ display: 'flex', gap: 24, marginTop: 16, flexWrap: 'wrap' }}>
            <div>
              <div className="t-meta">{t('cumulPnl')}</div>
              <div className={`t-h3 t-num ${totalPnl >= 0 ? 'c-up' : 'c-down'}`}>
                {totalPnl >= 0 ? '+' : ''}${totalPnl.toFixed(0)} ({fmtPct(totalPnlPct)})
              </div>
            </div>
            <div>
              <div className="t-meta">{t('dayPnl')}</div>
              <div className={`t-h3 t-num ${dayChange >= 0 ? 'c-up' : 'c-down'}`}>
                {dayChange >= 0 ? '+' : ''}${dayChange.toFixed(0)}
              </div>
            </div>
            <div>
              <div className="t-meta">{t('weightedRisk')}</div>
              <div className="t-h3 t-num">{riskScore < 30 ? t('riskLow') : riskScore < 60 ? t('riskMid') : t('riskHigh')}</div>
            </div>
          </div>
        </div>
        <div className="pf-hero-right">
          <PortfolioMiniChart totalValue={totalValue} totalCost={totalCost} />
        </div>
      </div>

      <div className="grid" style={{ gridTemplateColumns: '1fr 1.5fr', gap: 16 }}>
        {/* Allocation */}
        <div className="card">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 4 }}>
            <div style={{ fontWeight: 700 }}>{t('allocation')}</div>
            <div className="t-meta" style={{ fontSize: 11 }}>{t('basedOnValue')}</div>
          </div>
          <div className="t-meta" style={{ marginBottom: 14 }}>{t('allocationByClassUSD')}</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
            <DonutChart items={allocation} size={160} />
            <div style={{ flex: 1, minWidth: 160 }}>
              {allocation.map(a => {
                const pct = (a.value / totalValue) * 100;
                return (
                  <div key={a.label} style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                    <div style={{ width: 8, height: 8, borderRadius: 2, background: a.color }} />
                    <div style={{ flex: 1, fontSize: 13, fontWeight: 600 }}>{a.label}</div>
                    <div style={{ textAlign: 'right' }}>
                      <div className="t-num" style={{ fontWeight: 700, fontSize: 13 }}>${a.value.toLocaleString('en-US', { maximumFractionDigits: 0 })}</div>
                      <div className="t-num t-meta" style={{ fontSize: 11 }}>{pct.toFixed(1)}%</div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        {/* Holdings */}
        <div className="card">
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
            <div style={{ fontWeight: 700 }}>{t('holdings')}</div>
            <button className="btn btn--ghost btn--sm" onClick={() => setShowAdd(true)}>{t('addHolding')}</button>
          </div>
          {rows.map(r => {
            const up = r.pnl >= 0;
            return (
              <div key={r.id} className="row" onClick={() => goto({ tab: 'holding', holding: { id: r.id, qty: r.qty, cost: r.cost, buyDate: r.buyDate, venue: r.venue } })}>
                <Coin id={r.id} symbol={r.asset.symbol} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 700 }}>{r.asset.symbol}</div>
                  <div className="t-meta">{r.qty.toLocaleString()} {t('tokenUnit')}</div>
                </div>
                <div style={{ textAlign: 'right' }}>
                  <div className="t-num" style={{ fontWeight: 700 }}>${r.value.toFixed(0)}</div>
                  <div className={`t-num ${up ? 'c-up' : 'c-down'}`} style={{ fontSize: 13, fontWeight: 600 }}>
                    {up ? '+' : ''}${r.pnl.toFixed(0)} ({fmtPct(r.pnlPct)})
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="section-head">
        <div>
          <h2>{t('watchlist')}</h2>
          <div className="sub">{t('watchlistSub')}</div>
        </div>
      </div>
      <div className="card">
        {CRYPTOLIVE_DATA.assets().filter(a => ['coin', 'buidl', 'qqq'].includes(a.id)).map(a => {
          const up = a.change24h >= 0;
          return (
            <div key={a.id} className="row" onClick={() => goto({ tab: 'detail', assetId: a.id })}>
              <Coin id={a.id} symbol={a.symbol} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontWeight: 700 }}>{a.symbol}</div>
                <div className="t-meta">{a.shortDesc}</div>
              </div>
              <div style={{ textAlign: 'right' }}>
                <div className="t-num" style={{ fontWeight: 700 }}>${fmtPrice(a.tokenPrice)}</div>
                <div className={`t-num ${up ? 'c-up' : 'c-down'}`} style={{ fontSize: 13, fontWeight: 600 }}>{fmtPct(a.change24h)}</div>
              </div>
            </div>
          );
        })}
      </div>

      {showAdd && (
        <AddPositionModal
          onClose={() => setShowAdd(false)}
          onAdd={(pos) => {
            const existing = holdings.find(h => h.id === pos.id);
            if (existing) {
              const totalQty = existing.qty + pos.qty;
              const blendedCost = ((existing.qty * existing.cost) + (pos.qty * pos.cost)) / totalQty;
              setHoldings(holdings.map(h => h.id === pos.id ? { id: pos.id, qty: totalQty, cost: blendedCost, buyDate: pos.buyDate, venue: pos.venue } : h));
            } else {
              setHoldings([...holdings, pos]);
            }
            const a = CRYPTOLIVE_DATA.assets().find(x => x.id === pos.id);
            setToast(t('addedToast', a.symbol, pos.qty));
            setTimeout(() => setToast(null), 2400);
          }}
        />
      )}
      {toast && (
        <div style={{ position: 'fixed', bottom: 96, left: '50%', transform: 'translateX(-50%)', background: 'var(--fg-1)', color: 'var(--bg)', padding: '12px 20px', borderRadius: 999, fontWeight: 600, fontSize: 14, zIndex: 200, boxShadow: 'var(--shadow-3)' }}>
          ✓ {toast}
        </div>
      )}
    </div>
  );
}

window.PortfolioScreen = PortfolioScreen;
