// H2Learn — Matching Algorithms / Explainable Logic

(function() {
  const D = window.H2Data;
  const { useState } = React;

  const AlgorithmsScreen = () => {
    const [selected, setSelected] = useState('sim');
    const algo = D.ALGORITHMS.find(a => a.key === selected) || D.ALGORITHMS[0];

    return (
      <div className="col" style={{padding: '32px 40px', gap: 32, maxWidth: 1400, margin:'0 auto'}}>

        {/* hero */}
        <div className="grid cols-12" style={{gap: 32, alignItems:'end'}}>
          <div className="col-span-7 col gap-3">
            <div className="eyebrow">How matching works</div>
            <h1 style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-4xl)', fontWeight:400, margin:0, letterSpacing:'-0.02em', lineHeight:1.05}}>
              Nine algorithms, one explainable graph.
            </h1>
            <p style={{fontSize:'var(--t-lg)', color:'var(--ink-2)', lineHeight: 1.5, margin:'8px 0 0', maxWidth: 640, textWrap:'pretty'}}>
              Every match in H2Learn is built from explicit signals you can audit. No black-box ranking — just nine well-named algorithm families that compare your questionnaire data with the rest of the ecosystem.
            </p>
          </div>
          <div className="col-span-5">
            <Card variant="elevated" style={{padding: 22, background:'var(--ink)', color: 'var(--surface)', border:'none'}}>
              <div className="eyebrow" style={{color:'var(--surface-3)', opacity: 0.6}}>The pipeline</div>
              <div className="col gap-3" style={{marginTop: 12}}>
                {[
                  {n:'01', l:'Questionnaire', d:'You answer guided questions.'},
                  {n:'02', l:'Normalize', d:'Answers become structured entities + tags.'},
                  {n:'03', l:'Signals', d:'Profile fingerprint + needs/offers/bottlenecks.'},
                  {n:'04', l:'Match', d:'Nine algorithms compare profiles & projects.'},
                  {n:'05', l:'Explain', d:'Every edge stores its reason.'},
                ].map(s => (
                  <div key={s.n} className="row items-baseline gap-3">
                    <span style={{fontFamily:'var(--font-display)', fontSize: 18, color:'var(--warm)', minWidth: 28}}>{s.n}</span>
                    <div className="col">
                      <span style={{fontSize:'var(--t-md)', fontWeight: 500, color:'var(--surface)'}}>{s.l}</span>
                      <span style={{fontSize:'var(--t-xs)', color:'var(--surface-3)', opacity: 0.7}}>{s.d}</span>
                    </div>
                  </div>
                ))}
              </div>
            </Card>
          </div>
        </div>

        {/* === Algorithm grid === */}
        <div className="col gap-4">
          <div className="section-head">
            <div className="col">
              <h2>Algorithm families</h2>
              <div className="desc">Click any card to see signals, formula, and a worked example.</div>
            </div>
            <div className="row gap-2">
              <Btn variant="ghost" icon="info" size="sm">Levels of explanation</Btn>
              <Btn variant="ghost" icon="download" size="sm">Algorithm reference (PDF)</Btn>
            </div>
          </div>

          <div className="grid cols-3" style={{gap: 12}}>
            {D.ALGORITHMS.map(a => (
              <AlgoCard key={a.key} a={a} on={selected===a.key} onClick={() => setSelected(a.key)}/>
            ))}
          </div>
        </div>

        {/* === Selected algorithm detail === */}
        <Card variant="elevated" style={{padding: 28}}>
          <div className="grid cols-12" style={{gap: 32}}>
            <div className="col-span-5 col gap-4">
              <div className="row items-center gap-2">
                <span style={{width:8, height:8, borderRadius:'50%', background: algo.color}}/>
                <div className="eyebrow">Algorithm · {algo.key}</div>
              </div>
              <h2 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-3xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em', lineHeight:1.05}}>{algo.name}</h2>
              <p style={{fontSize:'var(--t-lg)', color:'var(--ink-2)', margin:0, lineHeight: 1.5}}>{algo.plain}</p>

              <div className="card tight" style={{background:'var(--surface-3)', border:'1px solid var(--line)'}}>
                <div className="eyebrow" style={{marginBottom: 6}}>Formula family</div>
                <code style={{fontFamily:'var(--font-mono)', fontSize:'var(--t-sm)', color:'var(--ink)'}}>{algo.formula}</code>
              </div>

              <div className="col gap-2">
                <div className="label-hr">Signals it reads</div>
                <div className="row gap-1 flex-wrap">
                  {algo.signals.map(s => <Chip key={s} variant="outline">{s}</Chip>)}
                </div>
              </div>

              <div className="col gap-2">
                <div className="label-hr">Where in the questionnaire</div>
                <div className="col gap-1" style={{fontSize:'var(--t-sm)', color:'var(--ink-2)'}}>
                  {sourceMap[algo.key].map((s,i) => (
                    <div key={i} className="row items-center gap-2"><Icon name="arrowRight" size={11} color="var(--ink-3)"/><span>{s}</span></div>
                  ))}
                </div>
              </div>
            </div>

            <div className="col-span-7 col gap-4">
              <WorkedExample algoKey={algo.key}/>
            </div>
          </div>
        </Card>

        {/* === Edge anatomy === */}
        <Card variant="elevated" style={{padding: 28}}>
          <div className="row items-center justify-between flex-wrap gap-3">
            <div className="col gap-1">
              <div className="eyebrow">Anatomy of one edge</div>
              <h2 style={{fontFamily:'var(--font-display)', fontSize:'var(--t-2xl)', fontWeight:400, margin:0, letterSpacing:'-0.015em'}}>Every relationship in the graph stores its reason</h2>
            </div>
          </div>

          <div className="grid cols-12" style={{gap: 24, marginTop: 20}}>
            <div className="col-span-7">
              <EdgeAnatomy/>
            </div>
            <div className="col-span-5">
              <div className="col gap-2">
                <div className="label-hr">What every edge contains</div>
                <div className="col gap-2">
                  {[
                    ['source',           'Origin node id'],
                    ['target',           'Destination node id'],
                    ['type',             'One of 8 relationship types'],
                    ['strength',         '0–1 normalized score'],
                    ['confidence',       '0–1 system confidence'],
                    ['signals[]',        'Per-signal score + weight'],
                    ['explanation',      'Plain-English summary'],
                    ['evidence[]',       'Linked questionnaire answers'],
                    ['generatedAt',      'Timestamp · provenance'],
                    ['curatorReviewed',  'true / false / pending'],
                  ].map(([k,v]) => (
                    <div key={k} className="row justify-between" style={{padding: '6px 0', borderBottom:'1px dashed var(--line)'}}>
                      <code style={{fontFamily:'var(--font-mono)', fontSize:'var(--t-xs)', color:'var(--accent)'}}>{k}</code>
                      <span style={{fontSize:'var(--t-xs)', color:'var(--ink-3)'}}>{v}</span>
                    </div>
                  ))}
                </div>
              </div>
            </div>
          </div>
        </Card>

        {/* === Two levels of explanation === */}
        <div className="grid cols-2" style={{gap: 16}}>
          <Card>
            <Chip variant="accent">Level 1</Chip>
            <h3 style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-2xl)', fontWeight:400, margin:'12px 0 0', letterSpacing:'-0.015em'}}>User-friendly explanation</h3>
            <p style={{fontSize:'var(--t-md)', color:'var(--ink-2)', lineHeight: 1.55}}>Plain-English, action-oriented. "Sara matches HYDRO-NL because she offers exactly the membrane test method they need, and they share PEM expertise."</p>
            <div className="card tight" style={{background:'var(--accent-soft)', border:'none', marginTop: 12}}>
              <div style={{fontSize:'var(--t-sm)', color:'var(--accent)', lineHeight: 1.5}}>
                Default for every match card, network drawer, and dashboard recommendation.
              </div>
            </div>
          </Card>
          <Card>
            <Chip variant="outline">Level 2 · expandable</Chip>
            <h3 style={{fontFamily:'var(--font-display)', fontSize: 'var(--t-2xl)', fontWeight:400, margin:'12px 0 0', letterSpacing:'-0.015em'}}>Technical details</h3>
            <p style={{fontSize:'var(--t-md)', color:'var(--ink-2)', lineHeight: 1.55}}>Optional expandable section for analysts and curators. Shows formulas, signal weights, edge metadata, and source data.</p>
            <div className="card tight" style={{background:'var(--surface-3)', marginTop: 12, fontFamily:'var(--font-mono)', fontSize: 11, color:'var(--ink-2)'}}>
              cosine(fp_a, fp_b) · 0.4<br/>
              + jaccard(domains_a, domains_b) · 0.15<br/>
              + needoffer(a, b) · 0.30<br/>
              + project_compat(a, b) · 0.15
            </div>
          </Card>
        </div>

        <div className="text-center" style={{padding: 16}}>
          <Btn variant="primary" size="lg" icon="arrowRight" iconRight="arrowRight" onClick={() => location.hash='match'}>See it in action — open a match</Btn>
        </div>
      </div>
    );
  };

  const sourceMap = {
    sim:       ['Q-knowledge — domains/subdomains', 'Q-weights — 100-point allocation', 'Q-fingerprint (derived)'],
    overlap:   ['Q-domains', 'Q-methods', 'Q-sectors'],
    needoffer: ['Q-needs · open resources you lack', 'Q-offers · resources you can share', 'Q-challenges · missing resource fields'],
    project:   ['Q-project — stage', 'Q-project — TRL', 'Q-project — scale & application'],
    antidup:   ['Q-challenges', 'Q-bottlenecks · severity 1–5', 'Q-bottlenecks · type (internal/external)'],
    uncertain: ['Q-uncertainties · domain', 'Q-uncertainties · planning horizon', 'Q-confidence levels'],
    bridge:    ['Q-orientation · cross-sector ties', 'Q-partners — types', 'derived bridge centrality'],
    method:    ['Q-methods — active toolkit', 'Q-challenges — required method'],
    central:   ['Graph adjacency (derived)', 'Cross-cluster edges (derived)', 'Eigenvector centrality (derived)'],
  };

  // ============ Algo card ============
  const AlgoCard = ({a, on, onClick}) => (
    <button onClick={onClick} className={'card lift'} style={{
      textAlign:'left',
      borderColor: on ? a.color : 'var(--line)',
      background: on ? 'var(--surface-2)' : 'var(--surface)',
      boxShadow: on ? `0 0 0 3px ${a.color}33` : 'none',
      padding: 18, cursor:'pointer',
    }}>
      <div className="row items-center gap-2" style={{marginBottom: 12}}>
        <span style={{width:10, height:10, borderRadius:'50%', background: a.color}}/>
        <span style={{fontSize: 10, color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'0.1em'}}>{a.key}</span>
      </div>
      <div style={{fontFamily:'var(--font-display)', fontSize:'var(--t-xl)', letterSpacing:'-0.015em', lineHeight:1.1, marginBottom: 8}}>{a.name}</div>
      <div style={{fontSize:'var(--t-sm)', color:'var(--ink-2)', lineHeight: 1.5, marginBottom: 12}}>{a.plain}</div>
      <code style={{fontFamily:'var(--font-mono)', fontSize: 11, color:'var(--ink-3)', display:'block', whiteSpace: 'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{a.formula}</code>
    </button>
  );

  // ============ Worked examples (per algo) ============
  const WorkedExample = ({algoKey}) => {
    if (algoKey === 'sim') return <ExSim/>;
    if (algoKey === 'needoffer') return <ExNeedOffer/>;
    if (algoKey === 'antidup') return <ExAntiDup/>;
    return <ExGeneric algoKey={algoKey}/>;
  };

  const ExSim = () => {
    const sara = D.PEOPLE.find(p => p.id === 'p_sara').fingerprint;
    const lies = D.PEOPLE.find(p => p.id === 'p_liesbeth').fingerprint;
    const allDomains = [...new Set([...sara.map(s=>s.d), ...lies.map(s=>s.d)])];
    return (
      <div className="col gap-3">
        <div className="eyebrow">Worked example · Sara × Liesbeth</div>
        <div className="card tight" style={{background:'var(--surface-3)'}}>
          <div className="col gap-2">
            {allDomains.map(d => {
              const sw = sara.find(x => x.d === d)?.w || 0;
              const lw = lies.find(x => x.d === d)?.w || 0;
              const max = 50;
              return (
                <div key={d} className="grid" style={{gridTemplateColumns: '120px 1fr 24px 1fr 24px', alignItems:'center', gap: 8}}>
                  <div style={{fontSize:'var(--t-xs)', color:'var(--ink-2)'}}>{d}</div>
                  <div className="bar" style={{height: 8}}>
                    <div className="fill" style={{background:'var(--c-person)', width: (sw/max*100) + '%', marginLeft: 'auto'}}/>
                  </div>
                  <span className="tnum" style={{fontSize:10, color:'var(--ink-3)', textAlign:'center'}}>{sw}</span>
                  <div className="bar" style={{height: 8}}>
                    <div className="fill" style={{background:'var(--accent)', width: (lw/max*100) + '%'}}/>
                  </div>
                  <span className="tnum" style={{fontSize:10, color:'var(--ink-3)', textAlign:'center'}}>{lw}</span>
                </div>
              );
            })}
          </div>
        </div>
        <div className="row gap-3 items-center justify-between">
          <div className="row gap-3">
            <Legend2 c="var(--c-person)" l="Sara"/>
            <Legend2 c="var(--accent)" l="Liesbeth"/>
          </div>
          <div className="row gap-2">
            <Chip variant="outline">cosine ≈ 0.92</Chip>
            <Chip variant="accent">contributes 40% of similarity score</Chip>
          </div>
        </div>
      </div>
    );
  };

  const ExNeedOffer = () => (
    <div className="col gap-3">
      <div className="eyebrow">Worked example · Sara × HYDRO-NL</div>
      <div className="grid cols-2" style={{gap: 12}}>
        <Card variant="tight" style={{borderColor:'var(--c-need)', borderWidth: 1}}>
          <div className="eyebrow" style={{color:'var(--c-need)'}}>HYDRO-NL · need</div>
          <div style={{fontSize:'var(--t-md)', fontWeight: 600, marginTop: 6}}>Membrane durability data</div>
          <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', marginTop: 4}}>From Q-challenges · "missing resource"</div>
        </Card>
        <Card variant="tight" style={{borderColor:'var(--c-offer)', borderWidth: 1}}>
          <div className="eyebrow" style={{color:'var(--c-offer)'}}>Sara · offer</div>
          <div style={{fontSize:'var(--t-md)', fontWeight: 600, marginTop: 6}}>Membrane test method</div>
          <div style={{fontSize:'var(--t-xs)', color:'var(--ink-3)', marginTop: 4}}>From Q-offers · open resource</div>
        </Card>
      </div>
      <div className="row items-center gap-3 justify-center" style={{padding:'8px 0'}}>
        <Icon name="arrowRight" color="var(--accent)"/>
        <Chip variant="accent" size="lg">match strength · 0.95</Chip>
        <Icon name="arrowLeft" color="var(--accent)"/>
      </div>
      <div style={{fontSize:'var(--t-sm)', color:'var(--ink-2)', lineHeight: 1.5}}>
        Token overlap on "membrane" + "durability" is 100%. The need-vs-offer alignment alone explains most of the match score.
      </div>
    </div>
  );

  const ExAntiDup = () => (
    <div className="col gap-3">
      <div className="eyebrow">Worked example · Bram × Liesbeth</div>
      <div className="card tight" style={{background:'rgba(176,58,46,0.06)', border:'1px solid rgba(176,58,46,0.2)'}}>
        <div className="row items-center gap-2" style={{marginBottom: 8}}>
          <Icon name="alert" color="var(--e-antidup)"/>
          <span style={{fontWeight:600, color:'var(--e-antidup)'}}>Both teams hitting the same wall</span>
        </div>
        <div className="col gap-2">
          <div className="row justify-between">
            <span style={{fontSize:'var(--t-sm)'}}>Challenge similarity</span>
            <span className="tnum" style={{fontSize:'var(--t-sm)', fontWeight:600}}>0.90</span>
          </div>
          <div className="row justify-between">
            <span style={{fontSize:'var(--t-sm)'}}>Bottleneck similarity</span>
            <span className="tnum" style={{fontSize:'var(--t-sm)', fontWeight:600}}>0.88</span>
          </div>
          <div className="divider dashed"/>
          <div className="row justify-between">
            <span style={{fontSize:'var(--t-sm)', fontWeight: 600}}>Product 0.90 × 0.88</span>
            <span className="tnum" style={{fontSize:'var(--t-md)', fontWeight:600, color:'var(--e-antidup)'}}>0.79 &gt; τ (0.6) ✓</span>
          </div>
        </div>
      </div>
      <div style={{fontSize:'var(--t-sm)', color:'var(--ink-2)'}}>Both flagged "membrane durability protocols" as their core challenge and "pilot data sharing" as their main external bottleneck. Coordination here would reduce parallel work.</div>
    </div>
  );

  const ExGeneric = ({algoKey}) => {
    const samples = {
      overlap:  { a:'Sara', b:'Liesbeth', shared:['PEM','Membrane','LCA'], score: '5/5 domains'},
      project:  { a:'GreenH2-PEM (TRL 4)', b:'HYDRO-NL (TRL 5)', shared:['Pilot scale','NL region'], score: 'compat 0.78'},
      uncertain:{ a:'Sara', b:'Nora', shared:['simulation-field gap','3-yr horizon'], score: 'overlap 0.80'},
      bridge:   { a:'Iteke', b:'Lori', shared:['research↔education','industry↔policy'], score: 'bridge 0.92 / 0.88'},
      method:   { a:'Nora · digital twin', b:'HYDRO-NL · model gap', shared:['simulation','TEA'], score:'transfer 0.85'},
      central:  { a:'Iteke', b:'graph', shared:['betweenness','degree'], score:'top decile'},
    };
    const s = samples[algoKey] || samples.overlap;
    return (
      <div className="col gap-3">
        <div className="eyebrow">Worked example · {s.a} × {s.b}</div>
        <div className="card tight">
          <div className="row gap-2 flex-wrap">{s.shared.map(x => <Chip key={x} variant="accent">{x}</Chip>)}</div>
          <div className="divider dashed"/>
          <div className="row justify-between">
            <span style={{fontSize:'var(--t-sm)', color:'var(--ink-3)'}}>Result</span>
            <span style={{fontWeight:600}}>{s.score}</span>
          </div>
        </div>
      </div>
    );
  };

  const Legend2 = ({c, l}) => (
    <div className="row items-center gap-2"><span style={{width:10,height:10,background:c,borderRadius:2}}/><span style={{fontSize:'var(--t-xs)'}}>{l}</span></div>
  );

  // ============ Edge anatomy: visual edge with all metadata ============
  const EdgeAnatomy = () => {
    const m = D.MATCHES[0]; // Sara × HYDRO-NL
    return (
      <div className="card tight" style={{padding: 22, background:'var(--surface-2)'}}>
        <svg viewBox="0 0 600 220" width="100%" height="220">
          <defs>
            <linearGradient id="edge-grad" x1="0" x2="1">
              <stop offset="0%" stopColor="var(--c-person)"/>
              <stop offset="100%" stopColor="var(--c-project)"/>
            </linearGradient>
          </defs>
          {/* edge */}
          <path d="M 110 110 Q 300 50, 490 110" stroke="url(#edge-grad)" strokeWidth="6" fill="none" strokeLinecap="round" opacity="0.85"/>
          {/* nodes */}
          <circle cx="110" cy="110" r="32" fill="#fff" stroke="var(--c-person)" strokeWidth="2"/>
          <text x="110" y="115" textAnchor="middle" fontFamily="Inter Tight" fontSize="14" fontWeight="700" fill="var(--c-person)">SA</text>
          <text x="110" y="160" textAnchor="middle" fontFamily="Inter Tight" fontSize="11" fill="var(--ink-2)">Sara Arif</text>
          <text x="110" y="174" textAnchor="middle" fontFamily="Inter Tight" fontSize="9" fill="var(--ink-3)">person</text>
          <polygon points="490,80 514,94 514,124 490,140 466,124 466,94" fill="#fff" stroke="var(--c-project)" strokeWidth="2"/>
          <text x="490" y="115" textAnchor="middle" fontFamily="Inter Tight" fontSize="14" fontWeight="700" fill="var(--c-project)">HN</text>
          <text x="490" y="160" textAnchor="middle" fontFamily="Inter Tight" fontSize="11" fill="var(--ink-2)">HYDRO-NL Pilot</text>
          <text x="490" y="174" textAnchor="middle" fontFamily="Inter Tight" fontSize="9" fill="var(--ink-3)">project</text>

          {/* annotations */}
          <line x1="300" y1="40" x2="300" y2="68" stroke="var(--ink-3)" strokeDasharray="2 3"/>
          <text x="300" y="30" textAnchor="middle" fontFamily="Inter Tight" fontSize="11" fontWeight="600" fill="var(--ink)">type · Complementarity</text>

          <line x1="220" y1="100" x2="220" y2="130" stroke="var(--ink-3)" strokeDasharray="2 3"/>
          <text x="195" y="200" textAnchor="middle" fontFamily="Inter Tight" fontSize="10" fill="var(--ink-3)">strength 0.88</text>

          <line x1="380" y1="100" x2="380" y2="130" stroke="var(--ink-3)" strokeDasharray="2 3"/>
          <text x="405" y="200" textAnchor="middle" fontFamily="Inter Tight" fontSize="10" fill="var(--ink-3)">confidence 0.92</text>
        </svg>
        <div className="divider"/>
        <div style={{fontSize:'var(--t-xs)', fontFamily:'var(--font-mono)', color:'var(--ink-2)', lineHeight:1.7}}>
          {`{
  source: "p_sara", target: "pj_hydronl",
  type: "Complementarity", strength: 0.88, confidence: 0.92,
  signals: [ {needOffer: 0.95}, {subdomain: 0.78}, ... ],
  explanation: "${m.summary.slice(0, 60)}…",
  curatorReviewed: true, generatedAt: "2026-03-14"
}`}
        </div>
      </div>
    );
  };

  Object.assign(window, { AlgorithmsScreen });
})();
