/* ============================================================
   Dashboard.jsx — pantalla central (/)
   ============================================================ */
function MetricCard({ label, icon, value, cur, foot, accent }) {
  return (
    <div className="metric">
      <div className="accent-edge" style={{ background: accent }} />
      <div className="m-label"><Icon name={icon} size={14} className="ico" />{label}</div>
      <div className="m-value">{cur && <span className="cur">{cur}</span>}{value}</div>
      <div className="m-foot">{foot}</div>
    </div>
  );
}

function OppRow({ o, rank, onHover, onGo }) {
  const scoreColor = !o.score ? 'var(--text-3)'
    : o.score >= 68 ? 'var(--pos)' : o.score >= 52 ? 'var(--info)' : 'var(--warn)';
  return (
    <div className="opp" onClick={onGo} style={{ alignItems: 'flex-start', gap: 10 }}>
      <div className="rank" style={{ marginTop: 2 }}>{rank}</div>
      <div className="opp-main" style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 2 }}>
          <span className="opp-tk">{o.tk}</span>
          {o.score != null && (
            <span className="num" style={{ fontSize: 11, fontWeight: 700, color: scoreColor, background: 'var(--surface-3)', padding: '1px 6px', borderRadius: 4 }}>
              {o.score}
            </span>
          )}
          {o.isBono && o.tir != null && (
            <span className="num" style={{ fontSize: 11, color: 'var(--info)' }}>TIR {o.tir.toFixed(1)}%</span>
          )}
        </div>
        <div className="opp-nm">{o.nm}</div>
        {o.reason && (
          <div className="muted-note" style={{ fontSize: 10.5, marginTop: 3, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '100%' }}>
            {o.reason}
          </div>
        )}
      </div>
      <div className="opp-px" style={{ flexShrink: 0, textAlign: 'right' }}>
        {o.px != null && (
          <div className="num" style={{ fontSize: 13, fontWeight: 600 }}>
            {o.isBono ? 'US$' + fmtNum(o.px, 2) : o.px >= 1000 ? fmtARS(o.px) : 'US$' + fmtNum(o.px, 2)}
          </div>
        )}
        {o.v != null && <Delta value={o.v} />}
      </div>
      <div style={{ width: 86, textAlign: 'right', flexShrink: 0 }}>
        <Signal s={o} onHover={onHover} />
      </div>
    </div>
  );
}

function SkeletonLine({ w = '60%', h = 18 }) {
  return <div style={{ width: w, height: h, borderRadius: 4, background: 'var(--surface-3)', animation: 'shimmer 1.4s ease infinite', backgroundSize: '200% 100%' }} />;
}

/* ---- Card Pionex real ---- */
function PionexCard({ pionex, loading }) {
  const hasCfg = !!localStorage.getItem('fin_pionex_key');
  if (!hasCfg) {
    return (
      <div className="card">
        <div className="card-head">
          <div className="card-title"><Icon name="market" size={16} className="ico" />Pionex</div>
        </div>
        <div className="empty-state" style={{ padding: '24px 0', textAlign: 'center', color: 'var(--text-3)' }}>
          <Icon name="bank" size={28} style={{ opacity: .4, marginBottom: 10 }} /><br />
          <span style={{ fontSize: 13 }}>Conectá Pionex en Configuración</span>
        </div>
      </div>
    );
  }

  const bots     = pionex?.bots     || [];
  const balances = pionex?.balances || [];
  const errMsg   = pionex?.error;
  const usdt     = balances.find(b => b.asset === 'USDT');
  const totalPnl = bots.reduce((s, b) => s + (b.pnl || 0), 0);
  const hasBots  = bots.length > 0;

  return (
    <div className="card">
      <div className="card-head">
        <div className="card-title"><Icon name="market" size={16} className="ico" />Pionex · crypto</div>
        <a href="https://www.pionex.com/en/bots" target="_blank" rel="noreferrer" className="btn btn-ghost btn-sm">
          Abrir <Icon name="arrowUpRight" size={14} />
        </a>
      </div>

      {errMsg && (
        <div className="alert warn" style={{ marginBottom: 12, padding: '8px 12px' }}>
          <Icon name="alertTri" size={14} className="a-ico" /><span className="a-body">{errMsg}</span>
        </div>
      )}

      {loading && !errMsg && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <SkeletonLine w="60%" h={24} /><SkeletonLine w="80%" h={20} /><SkeletonLine w="70%" h={20} />
        </div>
      )}

      {!loading && !errMsg && (
        <>
          {usdt && (
            <div style={{ display: 'flex', gap: 20, marginBottom: 14 }}>
              <div>
                <div className="muted-note" style={{ fontSize: 11 }}>Disponible USDT</div>
                <div className="num" style={{ fontSize: 17, fontWeight: 700, color: 'var(--pos)' }}>
                  US${fmtNum(usdt.free, 2)}
                </div>
              </div>
              {usdt.frozen > 0.01 && (
                <div>
                  <div className="muted-note" style={{ fontSize: 11 }}>En bots</div>
                  <div className="num" style={{ fontSize: 17, fontWeight: 700 }}>
                    US${fmtNum(usdt.frozen, 2)}
                  </div>
                </div>
              )}
              {hasBots && (
                <div>
                  <div className="muted-note" style={{ fontSize: 11 }}>P&L bots</div>
                  <div className="num" style={{ fontSize: 17, fontWeight: 700, color: totalPnl >= 0 ? 'var(--pos)' : 'var(--neg)' }}>
                    {totalPnl >= 0 ? '+' : ''}US${fmtNum(totalPnl, 2)}
                  </div>
                </div>
              )}
            </div>
          )}

          {hasBots && (
            <>
              <div className="divider" />
              <div style={{ fontSize: 11.5, fontWeight: 600, color: 'var(--text-3)', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 8, marginTop: 4 }}>
                Bots activos ({bots.length})
              </div>
              {bots.slice(0, 4).map(b => (
                <div key={b.id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '5px 0', borderTop: '1px solid var(--border)' }}>
                  <div>
                    <div style={{ fontSize: 12.5, fontWeight: 600 }}>{b.symbol}</div>
                    <div className="muted-note" style={{ fontSize: 11 }}>{b.name?.replace(/_/g, ' ')}</div>
                  </div>
                  <div style={{ textAlign: 'right' }}>
                    <div className="num" style={{ fontSize: 12.5, fontWeight: 600, color: b.pnl >= 0 ? 'var(--pos)' : 'var(--neg)' }}>
                      {b.pnl >= 0 ? '+' : ''}US${fmtNum(b.pnl, 2)}
                    </div>
                    {b.pnlPct !== 0 && (
                      <div className="num" style={{ fontSize: 11, color: b.pnlPct >= 0 ? 'var(--pos)' : 'var(--neg)' }}>
                        {b.pnlPct >= 0 ? '+' : ''}{fmtNum(b.pnlPct, 2)}%
                      </div>
                    )}
                  </div>
                </div>
              ))}
            </>
          )}

          {!hasBots && !usdt && (
            <div className="empty-state" style={{ padding: '16px 0', color: 'var(--text-3)', fontSize: 13 }}>
              Sin posiciones activas en Pionex
            </div>
          )}
        </>
      )}
    </div>
  );
}

/* ---- Card de noticias ---- */
const SOURCE_COLORS = {
  'Ámbito':          '#ffb020',
  'Cronista':        '#4488ff',
  'Infobae':         '#ff6b9d',
  'Google News AR':  '#00ff88',
  'Google News Int': '#a06bff',
};

function NewsCard({ news, loading }) {
  const [expanded, setExpanded] = useState(false);
  const visible = expanded ? news : news.slice(0, 6);

  return (
    <div className="card" style={{ gridColumn: '1 / -1' }}>
      <div className="card-head">
        <div className="card-title"><Icon name="bell" size={16} className="ico" />Noticias financieras</div>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          {Object.entries(SOURCE_COLORS).map(([src, color]) => (
            <span key={src} style={{ fontSize: 10.5, color: 'var(--text-3)', display: 'flex', alignItems: 'center', gap: 3 }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: color, display: 'inline-block' }} />{src}
            </span>
          ))}
        </div>
      </div>

      {loading && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {[1,2,3,4].map(i => <SkeletonLine key={i} w={i % 2 === 0 ? '70%' : '85%'} h={18} />)}
        </div>
      )}

      {!loading && news.length === 0 && (
        <div className="empty-state" style={{ padding: '20px 0', color: 'var(--text-3)', textAlign: 'center' }}>
          Sin noticias disponibles
        </div>
      )}

      {!loading && news.length > 0 && (
        <>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '2px 16px' }}>
            {visible.map((n, i) => (
              <a key={i} href={n.link} target="_blank" rel="noreferrer"
                style={{ display: 'flex', flexDirection: 'column', gap: 3, padding: '9px 0', borderTop: i > 0 ? '1px solid var(--border)' : 'none', textDecoration: 'none', color: 'inherit' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <span style={{ width: 5, height: 5, borderRadius: '50%', background: SOURCE_COLORS[n.source] || 'var(--text-3)', flexShrink: 0 }} />
                  <span style={{ fontSize: 10.5, color: 'var(--text-3)', letterSpacing: '0.03em' }}>{n.source} · {n.date}</span>
                </div>
                <div style={{ fontSize: 13, fontWeight: 500, lineHeight: 1.4, color: 'var(--text-1)' }}
                  onMouseEnter={e => e.currentTarget.style.color = 'var(--pos)'}
                  onMouseLeave={e => e.currentTarget.style.color = 'var(--text-1)'}>
                  {n.title}
                </div>
              </a>
            ))}
          </div>
          {news.length > 6 && (
            <button className="btn btn-ghost btn-sm" style={{ marginTop: 10, width: '100%', justifyContent: 'center' }}
              onClick={() => setExpanded(e => !e)}>
              {expanded ? 'Ver menos' : `Ver ${news.length - 6} noticias más`}
              <Icon name={expanded ? 'up' : 'down'} size={13} />
            </button>
          )}
        </>
      )}
    </div>
  );
}

/* ---- Top 5 real con datos live ---- */
const SIG_STYLE = {
  COMPRAR:  { bg: 'color-mix(in oklab, var(--pos) 12%, var(--surface))',  color: 'var(--pos)',  label: 'COMPRAR'  },
  ACUMULAR: { bg: 'color-mix(in oklab, var(--info) 12%, var(--surface))', color: 'var(--info)', label: 'ACUMULAR' },
  ESPERAR:  { bg: 'color-mix(in oklab, var(--warn) 10%, var(--surface))', color: 'var(--warn)', label: 'ESPERAR'  },
  VENDER:   { bg: 'color-mix(in oklab, var(--neg)  12%, var(--surface))', color: 'var(--neg)',  label: 'VENDER'   },
};
const CLS_COLOR = { Bono: 'var(--info)', Acción: 'var(--pos)', CEDEAR: 'var(--warn)' };

function Top5Card({ top5, loading, go }) {
  const isEmpty = !loading && top5.length === 0;
  return (
    <div className="card">
      <div className="card-head">
        <div className="card-title">
          <Icon name="sparkle" size={16} className="ico" style={{ color: 'var(--pos)' }} />
          Top 5 · oportunidades reales
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ width: 7, height: 7, borderRadius: '50%', background: 'var(--pos)', display: 'inline-block', animation: 'pulse 2s infinite' }} />
          <span style={{ fontSize: 11, color: 'var(--text-3)' }}>precios live</span>
        </div>
      </div>
      <style>{`@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:.4} }`}</style>

      {loading && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: '4px 0' }}>
          {[1,2,3,4,5].map(i => <SkeletonLine key={i} w={i%2===0?'80%':'90%'} h={44} />)}
        </div>
      )}

      {isEmpty && (
        <div className="empty-state" style={{ padding: '28px 0', color: 'var(--text-3)', textAlign: 'center' }}>
          <Icon name="alertTri" size={24} style={{ opacity: .4, marginBottom: 8 }} /><br />
          Sin datos live disponibles
        </div>
      )}

      {!loading && top5.map((a, i) => {
        const sig = SIG_STYLE[a.signal] || SIG_STYLE.ESPERAR;
        return (
          <div key={a.tk} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 0', borderTop: i > 0 ? '1px solid var(--border)' : 'none' }}>
            {/* Rank */}
            <div style={{ width: 22, height: 22, borderRadius: '50%', background: 'var(--surface-3)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 700, color: 'var(--text-2)', flexShrink: 0, marginTop: 2 }}>
              {i + 1}
            </div>
            {/* Info */}
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 2 }}>
                <span style={{ fontFamily: 'var(--mono)', fontWeight: 700, fontSize: 13 }}>{a.tk}</span>
                <span style={{ fontSize: 10, padding: '1px 5px', borderRadius: 3, background: `color-mix(in oklab, ${CLS_COLOR[a.cls]||'gray'} 15%, var(--surface-3))`, color: CLS_COLOR[a.cls]||'var(--text-3)', fontWeight: 600 }}>{a.cls}</span>
                {a.tir != null && (
                  <span style={{ fontSize: 11, color: 'var(--info)', fontFamily: 'var(--mono)' }}>TIR {a.tir.toFixed(1)}%</span>
                )}
              </div>
              <div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 2 }}>{a.nm}</div>
              {a.reason && (
                <div style={{ fontSize: 10.5, color: 'var(--text-3)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{a.reason}</div>
              )}
            </div>
            {/* Precio + señal */}
            <div style={{ textAlign: 'right', flexShrink: 0 }}>
              {a.px != null && (
                <div style={{ fontFamily: 'var(--mono)', fontSize: 13, fontWeight: 600, marginBottom: 2 }}>
                  {a.cls === 'Bono' ? `US$${fmtNum(a.px, 2)}` : `$${fmtNum(a.pxARS ?? 0, 0)}`}
                </div>
              )}
              {a.v != null && <Delta value={a.v} />}
              <div style={{ marginTop: 4, fontSize: 10.5, fontWeight: 700, padding: '2px 7px', borderRadius: 4, background: sig.bg, color: sig.color, display: 'inline-block' }}>
                {sig.label}
              </div>
            </div>
          </div>
        );
      })}

      {!loading && top5.length > 0 && (
        <button className="btn btn-ghost btn-sm" style={{ width: '100%', justifyContent: 'center', marginTop: 8 }}
          onClick={() => go('mercado')}>
          Ver mercado completo <Icon name="arrowUpRight" size={13} />
        </button>
      )}
    </div>
  );
}

function Dashboard({ go, invPct, data, loading, errors, news = [], top5 = [] }) {
  const { onHover, node } = useTooltip();
  const mep = data._mepRate || 1;
  const pf  = window.STATIC.computePortfolio(data._priceMap || {}, mep);

  const series  = data.finance.series;
  const hasSeries = series.length >= 2;
  const last    = hasSeries ? series[series.length - 1] : null;
  const prev    = hasSeries ? series[series.length - 2] : null;
  const saldo   = last ? last.ingreso - last.gasto : 0;
  const prevSaldo = prev ? prev.ingreso - prev.gasto : 0;
  const saldoDelta = prevSaldo ? ((saldo / prevSaldo - 1) * 100) : 0;
  const disponible = Math.round(saldo * (invPct / 100));
  const last3   = series.slice(-3);

  return (
    <div className="content-inner page-enter">
      {node}
      <style>{`@keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }`}</style>

      <div className="metric-grid" style={{ marginBottom: 22 }}>
        <MetricCard label="Saldo del mes" icon="wallet"
          value={loading ? <SkeletonLine /> : fmtNum(saldo)} cur={loading ? '' : '$'} accent="var(--pos)"
          foot={hasSeries ? <><Delta value={saldoDelta} /><span className="muted-note">vs mes anterior</span></> : <span className="muted-note">sin datos de sheet</span>} />
        <MetricCard label="Disponible para invertir" icon="target"
          value={loading ? <SkeletonLine /> : fmtNum(disponible)} cur={loading ? '' : '$'} accent="var(--info)"
          foot={<span className="muted-note">{invPct}% del saldo del mes</span>} />
        <MetricCard label="Valor del portfolio" icon="coins"
          value={loading ? <SkeletonLine /> : fmtNum(Math.round(pf.totalMV))} cur={loading ? '' : '$'} accent="var(--warn)"
          foot={<span className="muted-note">{pf.rows.length} posiciones · Balanz + Cocos</span>} />
        <MetricCard label="Rendimiento total" icon="trending"
          value={loading ? <SkeletonLine /> : fmtPct(pf.totalPct)} accent={pf.totalPct >= 0 ? 'var(--pos)' : 'var(--neg)'}
          foot={<span className="num" style={{ color: pf.totalPnl >= 0 ? 'var(--pos)' : 'var(--neg)' }}>
            {loading ? <SkeletonLine w="40%" /> : (pf.totalPnl >= 0 ? '+' : '') + fmtARS(pf.totalPnl)}
          </span>} />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16, marginBottom: 22 }} className="dash-cols">
        <div className="card">
          <div className="card-head">
            <div className="card-title"><Icon name="wallet" size={16} className="ico" />Gastos · últimos meses</div>
            <button className="btn btn-ghost btn-sm" onClick={() => go('gastos')}>Ver finanzas <Icon name="arrowUpRight" size={14} /></button>
          </div>
          {last3.length > 0
            ? <>
                <MiniBars data={last3} valueKey="gasto" accent="var(--neg)" />
                <div className="divider" />
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
                  <div>
                    <div className="muted-note">Promedio {last3.length} meses</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600, marginTop: 3 }}>
                      {fmtARS(Math.round(last3.reduce((s, d) => s + d.gasto, 0) / last3.length))}
                    </div>
                  </div>
                  {last && <div style={{ textAlign: 'right' }}>
                    <div className="muted-note">Este mes</div>
                    <div className="num" style={{ fontSize: 16, fontWeight: 600, marginTop: 3 }}>{fmtARS(last.gasto)}</div>
                  </div>}
                </div>
              </>
            : <div className="empty-state" style={{ padding: '32px 0', textAlign: 'center', color: 'var(--text-3)' }}>
                <Icon name="sheet" size={28} style={{ opacity: .4, marginBottom: 10 }} /><br />
                Conectá tu Google Sheet para ver gastos
              </div>
          }
        </div>

        <Top5Card top5={top5} loading={loading} go={go} />

        <PionexCard pionex={data.pionex} loading={loading} />
      </div>

      <div style={{ display: 'grid', gap: 16, marginBottom: 22 }}>
        <NewsCard news={news} loading={loading} />
      </div>

      {Object.values(errors || {}).some(Boolean) && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {Object.entries(errors).filter(([,v])=>v).map(([k,msg]) => (
            <div key={k} className="alert warn">
              <Icon name="alertTri" size={17} className="a-ico" />
              <div><div className="a-title">{k.toUpperCase()} no disponible</div><div className="a-body">{msg}</div></div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { Dashboard });
