// watchlist.jsx — volglijst (tabel + kaarten) en de centrale evaluatie-helper.
const { useState: useStateWL } = React;

// Evalueer een aandeel onder de gekozen lens + veiligheidsmarge.
function evaluateStock(stock) {
  const lens = stock.lens || stock.defaultLens;
  const inp = stock.inputs;
  const val = lens === 'dividend' ? dividendValuation(stock, inp) : growthValuation(stock, inp);
  const composite = val.composite;
  const buy = buyPrice(composite, inp.safetyMargin);
  const status = valuationStatus(stock.price, composite);
  const upside = Number.isFinite(composite) ? (composite - stock.price) / stock.price : NaN;
  const hist = historicalCAGR(stock.history, stock.dividendRate, stock.divHistory);
  // groei waarmee de reële waarde meegroeit: dividendgroei onder de dividendlens,
  // (gecapte) winstgroei onder de groeilens — dezelfde g als in de methodes
  const g = lens === 'dividend'
    ? Math.min(inp.divGrowth, 0.15)
    : Math.min(inp.growth, inp.growthCap ?? Infinity);
  const proj = projectedCAGR({
    price: stock.price, composite, growth: g, dividend: stock.dividendRate, years: 5,
  });
  return { lens, val, composite, buy, status, upside, hist, proj,
           reason: Number.isFinite(composite) ? null : unknownReason(stock, lens, inp) };
}

// Waarom geen reële waarde? Liever een eerlijke reden dan een verzonnen getal.
function unknownReason(stock, lens, inp) {
  if (!(stock.price > 0)) return 'Geen actuele koers beschikbaar.';
  const spreadOk = inp.discountRate - inp.terminalGrowth >= 0.02 - 1e-9;
  if (lens === 'dividend') {
    if (!(inp.dividend > 0)) return 'Keert geen dividend uit — gebruik de groeilens.';
    if (!spreadOk) return 'Disconteringsvoet ligt minder dan 2%-punt boven de terminale groei.';
    return 'Cijfers voor de dividendmethodes niet beschikbaar.';
  }
  const eps = inp.eps, cf = inp.cashflowPerShare;
  if (eps == null && cf == null) return 'Winst en vrije kasstroom niet beschikbaar.';
  if (!(eps > 0) && !(cf > 0)) return 'Verlieslatend: winst en vrije kasstroom zijn negatief — deze waarderingsmethodes zijn niet van toepassing.';
  if (!(eps > 0) && !spreadOk) return 'Verlieslatend en disconteringsvoet < 2%-punt boven de terminale groei.';
  return 'Cijfers voor de groeimethodes niet beschikbaar.';
}

const STATUS_ORDER = { under: 0, fair: 1, over: 2, unknown: 3 };

function LensChip({ lens }) {
  return <span className={`lenschip lenschip--${lens}`}>{lens === 'dividend' ? 'Dividend' : 'Groei'}</span>;
}
function ChangeTag({ v }) {
  if (!Number.isFinite(v)) return <span className="chg">—</span>;
  return <span className={`chg ${v >= 0 ? 'chg--up' : 'chg--down'}`}>{signedPct(v, 2)}</span>;
}

// ── TABEL ─────────────────────────────────────────────────────────────────
function WatchlistTable({ rows, onSelect, onRemove, manage }) {
  const [sort, setSort] = useStateWL({ key: 'upside', dir: 'desc' });
  const sorted = [...rows].sort((a, b) => {
    let av, bv;
    switch (sort.key) {
      case 'name': av = a.stock.name; bv = b.stock.name; break;
      case 'price': av = a.stock.price; bv = b.stock.price; break;
      case 'fair': av = a.ev.composite; bv = b.ev.composite; break;
      case 'buy': av = a.ev.buy; bv = b.ev.buy; break;
      case 'status': av = STATUS_ORDER[a.ev.status]; bv = STATUS_ORDER[b.ev.status]; break;
      case 'proj': av = a.ev.proj; bv = b.ev.proj; break;
      default: av = a.ev.upside; bv = b.ev.upside;
    }
    if (typeof av === 'string') return sort.dir === 'asc' ? av.localeCompare(bv) : bv.localeCompare(av);
    av = Number.isFinite(av) ? av : -Infinity; bv = Number.isFinite(bv) ? bv : -Infinity;
    return sort.dir === 'asc' ? av - bv : bv - av;
  });
  const th = (key, label, align = 'right') => (
    <th className={`th th--${align} ${sort.key === key ? 'is-sorted' : ''}`}
        onClick={() => setSort((s) => ({ key, dir: s.key === key && s.dir === 'desc' ? 'asc' : 'desc' }))}>
      <span>{label}</span>
      <i className={`th__arrow ${sort.key === key ? (sort.dir === 'asc' ? 'up' : 'down') : ''}`} />
    </th>
  );
  return (
    <div className="tablewrap">
      <table className={`wtable ${manage ? 'is-manage' : ''}`}>
        <thead>
          <tr>
            {th('name', 'Aandeel', 'left')}
            {th('price', 'Koers')}
            <th className="th th--left th--nosort">52-weeks bereik</th>
            {th('fair', 'Reële waarde')}
            {th('buy', 'Koopprijs')}
            {th('status', 'Waardering', 'left')}
            {th('upside', 'Potentieel')}
            {th('proj', 'Verw. CAGR')}
            <th className="th th--rm th--nosort" aria-label="Verwijderen" />
          </tr>
        </thead>
        <tbody>
          {sorted.map(({ stock, ev }) => (
            <tr key={stock.ticker} onClick={() => onSelect(stock.ticker)} className="wrow">
              <td className="td td--name">
                <div className="tk">{stock.ticker}<LensChip lens={ev.lens} /></div>
                <div className="nm">{stock.name}</div>
              </td>
              <td className="td td--num">
                <div className="td__price">{fmtMoney(stock.price, stock.currency)}</div>
                <ChangeTag v={stock.dayChange} />
              </td>
              <td className="td td--range">
                <RangeBar low={stock.low52} high={stock.high52} price={stock.price} currency={stock.currency} compact />
              </td>
              <td className="td td--num">{fmtMoney(ev.composite, stock.currency)}</td>
              <td className="td td--num tone--under">{fmtMoney(ev.buy, stock.currency)}</td>
              <td className="td"><StatusPill status={ev.status} size="sm" /></td>
              <td className={`td td--num tone--${ev.status}`}>{signedPct(ev.upside)}</td>
              <td className="td td--num">{signedPct(ev.proj)}</td>
              <td className="td td--rm">
                <button className="rmbtn" title={`${stock.ticker} verwijderen`} aria-label={`${stock.ticker} verwijderen`}
                        onClick={(e) => { e.stopPropagation(); onRemove(stock.ticker); }}>
                  <svg width="13" height="13" viewBox="0 0 13 13"><path d="M3 3l7 7M10 3l-7 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /></svg>
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ── KAARTEN ───────────────────────────────────────────────────────────────
function WatchlistCards({ rows, onSelect, onRemove, manage }) {
  return (
    <div className={`cardgrid ${manage ? 'is-manage' : ''}`}>
      {rows.map(({ stock, ev }) => (
        <div key={stock.ticker} className={`scard scard--${ev.status}`} onClick={() => onSelect(stock.ticker)} role="button" tabIndex={0}>
          <button className="scard__rm" title={`${stock.ticker} verwijderen`} aria-label={`${stock.ticker} verwijderen`}
                  onClick={(e) => { e.stopPropagation(); onRemove(stock.ticker); }}>
            <svg width="13" height="13" viewBox="0 0 13 13"><path d="M3 3l7 7M10 3l-7 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /></svg>
          </button>
          <div className="scard__top">
            <div>
              <div className="scard__tk">{stock.ticker}<LensChip lens={ev.lens} /></div>
              <div className="scard__nm">{stock.name}</div>
            </div>
            <StatusPill status={ev.status} size="sm" />
          </div>
          <div className="scard__price">
            <span className="scard__p">{fmtMoney(stock.price, stock.currency)}</span>
            <ChangeTag v={stock.dayChange} />
          </div>
          <RangeBar low={stock.low52} high={stock.high52} price={stock.price} currency={stock.currency} compact />
          <div className="scard__grid">
            <div className="scard__cell">
              <span>Reële waarde</span><b>{fmtMoney(ev.composite, stock.currency)}</b>
            </div>
            <div className="scard__cell">
              <span>Koopprijs</span><b className="tone--under">{fmtMoney(ev.buy, stock.currency)}</b>
            </div>
            <div className="scard__cell">
              <span>Potentieel</span><b className={`tone--${ev.status}`}>{signedPct(ev.upside)}</b>
            </div>
            <div className="scard__cell">
              <span>Verw. CAGR</span><b>{signedPct(ev.proj)}</b>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { evaluateStock, unknownReason, WatchlistTable, WatchlistCards, ChangeTag, LensChip });
