// Shared tokens, scenario data, micro-primitives used across all themes.
// Spanish microcopy. Data is the IBEX SIM intraday rebound scenario from the doc.

const FINAZ_TOKENS = {
  positive:   '#15803D',
  negative:   '#B91C1C',
  live:       '#2563EB',
  mock:       '#B45309',
  provenance: '#4F46E5',
  warning:    '#6D28D9',
  neutral:    '#64748B',
};

// ---------- IBEX SIM scenario (intraday) ----------
// 09:00 → 16:40, 10-min ticks. Falls morning, recovers from ~12:10.
// Generated deterministically so chart rendering is stable.
const SCENARIO = (() => {
  const open = 11_137.0;
  const high = 11_318.6;
  const low  = 11_018.4;
  const close = 11_275.4;
  const pts = [];
  // hand-tuned beats so the line matches the doc narrative
  const beats = [
    [ 0, 11137], [1, 11102], [2, 11078], [3, 11045], [4, 11018], // morning slide
    [ 5, 11035], [6, 11012], [7, 11055], [8, 11088], [9, 11102], // 10:30 macro chop
    [10, 11075], [11, 11070], [12, 11108], [13, 11150], [14, 11198], // 12:10 banca lead
    [15, 11230], [16, 11245], [17, 11252], [18, 11240], [19, 11258],
    [20, 11268], [21, 11290], [22, 11318], [23, 11305], [24, 11295], // 15:30 US open
    [25, 11280], [26, 11285], [27, 11272], [28, 11275],
  ];
  beats.forEach(([i, v]) => pts.push({ i, t: minToTime(540 + i * 10), v }));
  function minToTime(m) {
    const h = Math.floor(m / 60), mm = m % 60;
    return `${String(h).padStart(2,'0')}:${String(mm).padStart(2,'0')}`;
  }
  return {
    name: 'IBEX SIM',
    last: close,
    open, high, low,
    chgAbs: +138.4,
    chgPct: +1.24,
    drawdownPct: -2.80,
    volumeVsAvg: +18,
    series: pts,
    timeStart: '09:00',
    timeEnd: '16:40',
    sectors: [
      { name: 'Banca',        chg: +2.4, contrib: +0.62 },
      { name: 'Industria',    chg: +0.6, contrib: +0.11 },
      { name: 'Tech',         chg: +0.3, contrib: +0.05 },
      { name: 'Utilities',    chg: +0.1, contrib: +0.02 },
      { name: 'Consumo',      chg: -0.2, contrib: -0.03 },
      { name: 'Energía',      chg: -0.7, contrib: -0.10 },
      { name: 'Inmobiliario', chg: -1.0, contrib: -0.08 },
    ],
    events: [
      { time: '09:00', t: 0,  kind: 'open',   text: 'Apertura con presión bajista',         source: 'SIM-MKT-001' },
      { time: '10:30', t: 9,  kind: 'macro',  text: 'Dato macro menor al esperado',         source: 'SIM-NEWS-006' },
      { time: '12:10', t: 14, kind: 'sector', text: 'Banca lidera el rebote',               source: 'SIM-SECTOR-004' },
      { time: '15:30', t: 24, kind: 'live',   text: 'Apertura EEUU · volatilidad al alza',  source: 'SIM-MKT-002' },
      { time: '16:10', t: 27, kind: 'level',  text: 'Acercamiento a resistencia 11.340',    source: 'SIM-TECH-003' },
    ],
    watch: { soporte: 11_180, resistencia: 11_340 },
    sources: [
      { id: 'SIM-MKT-001',    label: 'Market feed intradía',     state: 'mock', timestamp: '16:40' },
      { id: 'SIM-SECTOR-004', label: 'Sector feed',               state: 'mock', timestamp: '16:38' },
      { id: 'SIM-TECH-003',   label: 'Technical overlay',         state: 'mock', timestamp: '16:30' },
      { id: 'SIM-NEWS-006',   label: 'Newsroom · nota editorial', state: 'mock', timestamp: '12:45' },
    ],
    claims: [
      { id: 'C1', text: 'Banca lidera el rebote',           status: 'validado'  },
      { id: 'C2', text: 'Volumen excepcional vs media 20s', status: 'pendiente' },
      { id: 'C3', text: 'Resistencia 11.340 a vigilar',     status: 'validado'  },
      { id: 'C4', text: 'Apuesta segura por bancos',        status: 'bloqueado' },
    ],
  };
})();

// ---------- shared geometry helpers ----------
function scenarioPath(width, height, padding = 0) {
  const { series } = SCENARIO;
  const xs = series.map(s => s.i);
  const ys = series.map(s => s.v);
  const xmin = Math.min(...xs), xmax = Math.max(...xs);
  const ymin = Math.min(...ys) - 6, ymax = Math.max(...ys) + 6;
  const w = width - padding * 2;
  const h = height - padding * 2;
  const px = (i) => padding + (i - xmin) / (xmax - xmin) * w;
  const py = (v) => padding + (1 - (v - ymin) / (ymax - ymin)) * h;
  let d = '';
  series.forEach((s, idx) => { d += (idx === 0 ? 'M' : 'L') + px(s.i).toFixed(2) + ' ' + py(s.v).toFixed(2); });
  const area = d + ` L${px(xmax).toFixed(2)} ${padding + h} L${px(xmin).toFixed(2)} ${padding + h} Z`;
  return { d, area, px, py, xmin, xmax, ymin, ymax };
}

// ---------- micro-primitives ----------
// State chips per the doc's data states.
function StateChip({ state, theme = 'light', size = 'sm' }) {
  const cfg = {
    LIVE:      { bg: FINAZ_TOKENS.live,       label: 'LIVE',      dot: true,  variant: 'solid' },
    DELAYED:   { bg: FINAZ_TOKENS.neutral,    label: 'DELAYED',   dot: false, variant: 'outline' },
    FROZEN:    { bg: '#0F172A',               label: 'FROZEN',    dot: false, variant: 'solid', icon: 'pause' },
    MOCK:      { bg: FINAZ_TOKENS.mock,       label: 'MOCK',      dot: false, variant: 'solid' },
    EST:       { bg: FINAZ_TOKENS.neutral,    label: 'EST',       dot: false, variant: 'dashed' },
    CORRECTED: { bg: FINAZ_TOKENS.warning,    label: 'CORRECTED', dot: false, variant: 'solid' },
  }[state] || { bg: '#64748B', label: state };
  const px = size === 'lg' ? '5px 10px' : '3px 7px';
  const fs = size === 'lg' ? 11 : 10;
  const dark = theme === 'dark';
  const styles = {
    base: {
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: px, borderRadius: 3,
      fontSize: fs, fontWeight: 600, letterSpacing: '0.06em',
      fontFamily: 'var(--mono)',
      textTransform: 'none',
      lineHeight: 1, whiteSpace: 'nowrap',
    },
    solid:   { background: cfg.bg, color: '#fff' },
    outline: { background: 'transparent', color: dark ? '#94A3B8' : cfg.bg, border: `1px solid ${dark ? '#334155' : cfg.bg}` },
    dashed:  { background: 'transparent', color: cfg.bg, border: `1px dashed ${cfg.bg}` },
  };
  const v = styles[cfg.variant || 'solid'];
  return (
    <span style={{ ...styles.base, ...v }}>
      {cfg.dot && <span style={{ width: 6, height: 6, borderRadius: 99, background: '#fff', boxShadow: '0 0 0 2px rgba(255,255,255,0.4)' }} />}
      {cfg.icon === 'pause' && <span style={{ display: 'inline-flex', gap: 1.5 }}>
        <span style={{ width: 2, height: 8, background: '#fff' }} />
        <span style={{ width: 2, height: 8, background: '#fff' }} />
      </span>}
      {cfg.label}
    </span>
  );
}

// Delta number with sign, used everywhere.
function Delta({ value, suffix = '%', size = 14, weight = 600, theme = 'light' }) {
  const positive = value >= 0;
  const color = positive ? FINAZ_TOKENS.positive : FINAZ_TOKENS.negative;
  const sign = positive ? '+' : '−';
  const abs = Math.abs(value).toFixed(2);
  return (
    <span style={{
      color, fontWeight: weight, fontSize: size,
      fontFamily: 'var(--mono)', fontVariantNumeric: 'tabular-nums', letterSpacing: '-0.01em',
    }}>{sign}{abs}{suffix}</span>
  );
}

// A token swatch row used in spec cards.
function Swatch({ name, hex, note, theme = 'light' }) {
  const dark = theme === 'dark';
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '36px 1fr auto', gap: 14, alignItems: 'center', padding: '10px 0', borderBottom: `1px solid ${dark ? '#1F2937' : '#EAE6DC'}` }}>
      <div style={{ width: 36, height: 36, borderRadius: 6, background: hex, boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.08)' }} />
      <div>
        <div style={{ fontSize: 12, fontWeight: 600, color: dark ? '#E2E8F0' : '#1A1B1F', fontFamily: 'var(--mono)' }}>{name}</div>
        {note && <div style={{ fontSize: 11, color: dark ? '#94A3B8' : '#64748B', marginTop: 2, lineHeight: 1.4 }}>{note}</div>}
      </div>
      <div style={{ fontSize: 11, color: dark ? '#94A3B8' : '#64748B', fontFamily: 'var(--mono)' }}>{hex}</div>
    </div>
  );
}

// Spec card section header.
function SpecHeading({ children, theme = 'light' }) {
  const dark = theme === 'dark';
  return (
    <div style={{
      fontSize: 10, fontWeight: 700, letterSpacing: '0.14em',
      textTransform: 'uppercase',
      color: dark ? '#94A3B8' : '#64748B',
      marginBottom: 12, marginTop: 24,
      fontFamily: 'var(--mono)',
    }}>{children}</div>
  );
}

// Do/Don't pill row.
function DoDont({ items, theme = 'light' }) {
  const dark = theme === 'dark';
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
      {items.map((it, i) => (
        <div key={i} style={{
          padding: '10px 12px',
          borderRadius: 6,
          background: it.kind === 'do'
            ? (dark ? 'rgba(21, 128, 61, 0.10)' : 'rgba(21, 128, 61, 0.07)')
            : (dark ? 'rgba(185, 28, 28, 0.10)' : 'rgba(185, 28, 28, 0.06)'),
          borderLeft: `2px solid ${it.kind === 'do' ? FINAZ_TOKENS.positive : FINAZ_TOKENS.negative}`,
        }}>
          <div style={{
            fontSize: 9, fontWeight: 700, letterSpacing: '0.12em',
            color: it.kind === 'do' ? FINAZ_TOKENS.positive : FINAZ_TOKENS.negative,
            fontFamily: 'var(--mono)', marginBottom: 4,
          }}>{it.kind === 'do' ? 'USAR' : 'EVITAR'}</div>
          <div style={{ fontSize: 12, lineHeight: 1.4, color: dark ? '#E2E8F0' : '#1A1B1F' }}>{it.text}</div>
        </div>
      ))}
    </div>
  );
}

// Mini watermark "MOCK" diagonal stripe used over chart placeholders.
function MockStripe({ opacity = 0.05 }) {
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none',
      backgroundImage: `repeating-linear-gradient(135deg, rgba(180,83,9,${opacity}) 0 12px, transparent 12px 24px)`,
    }} />
  );
}

Object.assign(window, {
  FINAZ_TOKENS, SCENARIO, scenarioPath,
  StateChip, Delta, Swatch, SpecHeading, DoDont, MockStripe,
});
