// data.jsx — AlphaSuite shared data + visual atoms

const AXES = [
  { key: 'product', label: 'Product Craft' },
  { key: 'tech',    label: 'Tech Stack & Security' },
  { key: 'velocity',label: 'Velocity' },
  { key: 'ai',      label: 'AI Durability' },
  { key: 'brand',   label: 'Brand & Positioning' },
  { key: 'mktg',    label: 'Marketing & Reputation' },
  { key: 'team',    label: 'Team & Founder' },
  { key: 'vision',  label: 'Vision & Feasibility' },
  { key: 'market',  label: 'Market & Competition' },
  { key: 'comm',    label: 'Commercial Engine' },
];

// Each company stores axis scores in AXES order
const COMPANIES = [
  {
    id: 'volta',
    name: 'Volta',
    sector: 'CleanTech',
    stage: 'Seed',
    arr: '£0.8m',
    growth: '+12%',
    score: 510,
    delta: -68,
    rag: 'red',
    headline: 'Commercial engine dropped to Red — Q1 revenue missed by 22%.',
    axes:    [58, 42, 55, 38, 44, 52, 61, 57, 49, 54],
    spark:   [610,600,585,575,565,548,538,528,520,510],
    runway:  '8 months',
    nrr:     '94%',
    weighting: 'VC',
  },
  {
    id: 'orbis',
    name: 'Orbis',
    sector: 'Fintech',
    stage: 'Series A',
    arr: '£2.9m',
    growth: '+28%',
    score: 680,
    delta: -20,
    rag: 'amber',
    headline: 'Stable. PSD3 compliance window narrowing — decision needed in 90 days.',
    axes:    [66, 74, 62, 71, 65, 63, 68, 74, 69, 68],
    spark:   [700,704,701,695,690,688,685,683,682,680],
    runway:  '17 months',
    nrr:     '112%',
    weighting: 'VC',
  },
  {
    id: 'smithfield',
    name: 'Smithfield',
    sector: 'B2B SaaS',
    stage: 'Series A',
    arr: '£2.1m',
    growth: '+34%',
    score: 720,
    delta: 70,
    rag: 'amber',
    headline: 'Strong product and team. AI durability and commercial concentration before Series B.',
    axes:    [82, 88, 79, 61, 68, 65, 85, 80, 63, 69],
    spark:   [640,650,660,665,675,685,690,700,710,720],
    runway:  '18 months',
    nrr:     '108%',
    weighting: 'VC',
    primary: true,
  },
  {
    id: 'helix',
    name: 'Helix',
    sector: 'HealthTech',
    stage: 'Series A',
    arr: '£1.4m',
    growth: '+45%',
    score: 790,
    delta: 72,
    rag: 'green',
    headline: 'NHS integration delayed but clinical evidence strengthens. AI compliance audit clean.',
    axes:    [84, 81, 78, 76, 68, 75, 82, 85, 77, 84],
    spark:   [710,720,728,740,748,760,768,775,782,790],
    runway:  '24 months',
    nrr:     '124%',
    weighting: 'VC',
  },
  {
    id: 'meridian',
    name: 'Meridian',
    sector: 'Deep Tech',
    stage: 'Series B',
    arr: '£4.8m',
    growth: '+67%',
    score: 840,
    delta: 32,
    rag: 'green',
    headline: 'Series B term sheet signed. Talent density and IP moat compounding.',
    axes:    [91, 88, 85, 82, 84, 80, 87, 88, 74, 81],
    spark:   [790,800,808,815,820,825,830,833,837,840],
    runway:  '36 months',
    nrr:     '141%',
    weighting: 'VC',
  },
];

// Axis 1-line commentary keyed by [companyId][axisIdx]
const AXIS_NOTES = {
  smithfield: [
    'Polished UI · strong UX research signals · mobile gaps flagged in Q3 roadmap',
    'Modern stack · SOC2 Type II passed this week · API security solid',
    'Two-week sprints · weekly releases · CI/CD mature, interim CTO started',
    'No clear AI-native moat — replicable without data flywheel strategy',
    'Clear value prop · underinvested in content and thought leadership',
    'Positive press but limited inbound demand-gen infrastructure',
    'Complementary founders · strong domain expertise · CTO hire pending',
    'Ambitious roadmap · 18-month runway · realistic milestones',
    'Growing market · two well-funded competitors entering adjacent space',
    'ARR £2.1m · NRR 108% · 71% concentrated in 3 accounts · no outbound',
  ],
  volta: [
    'Hardware iteration cycle slow · field returns unaddressed',
    'Legacy stack · firmware OTA pipeline brittle · no SOC posture',
    'Roadmap slipping two quarters · operations bottleneck',
    'No AI surface · automation not on roadmap',
    'Strong category POV undermined by Q1 miss',
    'Field-led sales · low brand recall outside SE England',
    'Lean team · key engineering departure flagged in March',
    'Vision intact, financial runway exposed without bridge',
    'Subsidy regime favourable but two consolidators emerging',
    'Q1 revenue missed by 22% · pipeline cover 0.8×',
  ],
  orbis: [
    'Clean compliant interface · feature parity reached Q4',
    'PCI in place · open-banking integration matured · PSD3 work tracking',
    'Steady release cadence · low incident rate',
    'Embedded fraud-scoring model in production · lacks evaluation harness',
    'Premium brand recognised in fintech circles',
    'B2B2C model — partner-led distribution working',
    'Stable founding team · COO recently joined ex-Wise',
    'Aggressive Series B target may exceed default runway',
    'TAM expanding · two large incumbents have copied core flow',
    'Healthy NRR 112% · transaction revenue plateau forming',
  ],
  helix: [
    'Clinician-grade UX · low training overhead reported in pilots',
    'HIPAA + GDPR clean · DICOM pipeline performant',
    'Pace governed by clinical validation — appropriate',
    'Imaging model evaluated quarterly · transparent confidence outputs',
    'Trusted in two NHS trusts · brand assets need refresh',
    'Limited outbound · relies on referral from clinical advisors',
    'CMO appointed Feb · clinical-leadership density now strong',
    'Long-cycle commercial model believable',
    'Adjacent diagnostics market crowded · differentiation in evidence',
    'Two enterprise pilots converted · annual contract length 24m',
  ],
  meridian: [
    'Best-in-class instrumentation UI · enterprise-feeling polish',
    'Bespoke compute fabric · IP moat documented',
    'Velocity sustained even at 60 engineers · uncommon',
    'Foundational research published · two papers under review',
    'Strong analyst recognition · thought leadership flywheel active',
    'ABM motion compounding · pipeline cover 3.4×',
    'Two cofounders + four director-level hires from Tier-1 labs',
    'Long-horizon vision matched with milestone discipline',
    'Hyper-specialised vertical · few credible competitors',
    'ARR £4.8m · NRR 141% · diversified across 11 logos',
  ],
};

// RAG resolver from score (matches VC weighting)
function ragOf(n) {
  if (n >= 75) return 'green';
  if (n >= 60) return 'amber';
  return 'red';
}

// Reusable swatch / dot
function RagDot({ rag, size = 8, style }) {
  const c = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' }[rag];
  return <span style={{
    display: 'inline-block', width: size, height: size, borderRadius: 999,
    background: c, ...style,
  }} />;
}

function RagBlock({ rag, w = 18, h = 18, style }) {
  const c = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' }[rag];
  return <span style={{
    display: 'inline-block', width: w, height: h, background: c, ...style,
  }} />;
}

// Mono kicker label — used everywhere
function Kicker({ children, color = 'var(--ink-3)', style }) {
  return <div style={{
    fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.14em',
    textTransform: 'uppercase', color, ...style,
  }}>{children}</div>;
}

// Hairline separator using elev color
function Rule({ tone = 'var(--elev-2)', style }) {
  return <div style={{ height: 1, background: tone, ...style }} />;
}

// Progress bar (no border, surface-contrast)
function AxisBar({ score, rag, h = 4, bg = 'var(--elev-1)' }) {
  const c = { red: 'var(--red)', amber: 'var(--amber)', green: 'var(--green)' }[rag];
  return (
    <div style={{ height: h, background: bg, position: 'relative', width: '100%' }}>
      <div style={{
        position: 'absolute', left: 0, top: 0, bottom: 0,
        width: `${score}%`, background: c,
        transformOrigin: 'left',
        animation: 'alpha-bar-fill 380ms ease-out 180ms both',
      }} />
    </div>
  );
}

// Tiny sparkline SVG (10 points)
function Spark({ data, w = 96, h = 24, color = 'var(--ink)', stroke = 1.5 }) {
  const max = Math.max(...data), min = Math.min(...data);
  const rng = Math.max(1, max - min);
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * (w - 2) + 1;
    const y = h - 1 - ((v - min) / rng) * (h - 2);
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: 'block' }}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth={stroke}
        strokeLinejoin="round" strokeLinecap="round"/>
    </svg>
  );
}

// Up/down delta marker (no emoji)
function Delta({ value, color, size = 12 }) {
  const up = value >= 0;
  const tri = up
    ? `M 0 ${size*0.78} L ${size/2} 0 L ${size} ${size*0.78} Z`
    : `M 0 ${size*0.22} L ${size/2} ${size} L ${size} ${size*0.22} Z`;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6, color: color || 'inherit', fontFamily: 'var(--mono)', fontSize: 12 }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ alignSelf: 'center' }}>
        <path d={tri} fill="currentColor"/>
      </svg>
      <span>{up ? '+' : ''}{value}</span>
    </span>
  );
}

// Right-chevron / arrow used in editorial moments
function Arrow({ size = 16, color = 'currentColor', style }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" style={style}>
      <path d="M3 8 H13 M9 4 L13 8 L9 12" stroke={color} strokeWidth="1.4" fill="none" strokeLinecap="square" strokeLinejoin="miter"/>
    </svg>
  );
}

function Chev({ size = 14, dir = 'left', color = 'currentColor' }) {
  const d = dir === 'left' ? 'M9 3 L4 8 L9 13' : 'M5 3 L10 8 L5 13';
  return (
    <svg width={size} height={size} viewBox="0 0 16 16">
      <path d={d} stroke={color} strokeWidth="1.5" fill="none" strokeLinecap="square"/>
    </svg>
  );
}

// Sorted axis indices for a company, worst-first
function worstFirst(company) {
  return company.axes
    .map((s, i) => ({ s, i }))
    .sort((a, b) => a.s - b.s)
    .map(x => x.i);
}

// Pre-computed: index in the AXES array
const AXIS_KEY = AXES.map(a => a.key);

// Get short axis label (for table heads etc.)
const AXIS_SHORT = {
  product: 'Prod', tech: 'Tech', velocity: 'Vel', ai: 'AI', brand: 'Brand',
  mktg: 'Mktg', team: 'Team', vision: 'Vision', market: 'Market', comm: 'Comm',
};

Object.assign(window, {
  AXES, AXIS_SHORT, COMPANIES, AXIS_NOTES,
  ragOf, RagDot, RagBlock, Kicker, Rule, AxisBar, Spark, Delta, Arrow, Chev,
  worstFirst, AxisFingerprint,
});

// ────────────────────────────────────────────────────────────
// AxisFingerprint — the 10-axis heatmap row, scaled across sizes
// Same principles at every scale: cell tinted by RAG, score in mono.
// Sizes get more abstract as they shrink — numbers drop, colour does the work.
//   xs: 10 hairline bars, height-encoded score, no numbers
//   sm: 10 narrow cells, no numbers, RAG tints
//   md: 10 cells with numbers (the heatmap matrix variant)
//   lg: same as md with axis labels above
// ────────────────────────────────────────────────────────────
function AxisFingerprint({ company, size = 'md', highlight = null, onCellClick, cellHeight }) {
  const axes = company.axes;
  const cellH = cellHeight || { xs: 28, sm: 22, md: 28, lg: 36 }[size];
  const gap   = { xs: 1,  sm: 1,  md: 1,  lg: 2 }[size];
  const fs    = { xs: 0,  sm: 0,  md: 11, lg: 13 }[size];

  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(10, 1fr)', gap }}>
      {axes.map((s, i) => {
        const rag = ragOf(s);
        const bg = { red: 'var(--red-deep)', amber: 'var(--amber-deep)', green: 'var(--green-deep)' }[rag];
        const fg = { red: 'var(--red)',      amber: 'var(--amber)',      green: 'var(--green)'      }[rag];
        const isHighlight = highlight === i;
        // xs: bar-height encoding — taller = better (so the worst axes "drop")
        if (size === 'xs') {
          const h = Math.max(3, Math.round((s / 100) * cellH));
          return (
            <div key={i} title={`${AXES[i].label}: ${s}`}
              onClick={() => onCellClick && onCellClick(i)}
              style={{
                height: cellH, background: 'var(--elev-1)',
                position: 'relative', cursor: onCellClick ? 'pointer' : 'default',
              }}>
              <div style={{
                position: 'absolute', left: 0, right: 0, bottom: 0,
                height: h, background: fg, opacity: isHighlight ? 1 : 0.85,
              }}/>
            </div>
          );
        }
        return (
          <div key={i} title={`${AXES[i].label}: ${s}`}
            onClick={() => onCellClick && onCellClick(i)}
            style={{
              height: cellH, background: bg,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'var(--mono)', fontSize: fs, color: fg,
              cursor: onCellClick ? 'pointer' : 'default',
              outline: isHighlight ? `1px solid ${fg}` : 'none',
              outlineOffset: isHighlight ? -1 : 0,
            }}>
            {fs > 0 ? s : null}
          </div>
        );
      })}
    </div>
  );
}
