/* results.jsx — full-screen parchment results overlay */
function ResultsOverlay({ quest, metrics, trials, params, onClose }) {
  const domainColor = {
    memory:'#4888c8', inhibition:'#c05570', flexibility:'#c8921c',
    attention:'#7050c8', executive:'#3aa878', visuospatial:'#c87030',
  }[quest.domain] || '#8a7a60';

  const subject = window.__themyndSubject || {};
  const subjectLine = [
    subject.name || null,
    subject.age !== '' && subject.age != null ? `${subject.age}歲` : null,
    subject.gender || null,
    subject.testDate ? `測驗日 ${subject.testDate}` : null,
  ].filter(Boolean).join('  ·  ');

  // FEA-012: shared filename slug + collected union of all trial keys (sparse trials
  // may have different fields per task; union ensures CSV header is stable).
  const fnameStem = `${(subject.name || 'anon').replace(/\s/g,'_')}_${quest.name.replace(/\s/g,'_')}_${Date.now()}`;
  const allKeys = (() => {
    const set = new Set();
    (trials || []).forEach(t => Object.keys(t || {}).forEach(k => set.add(k)));
    return [...set];
  })();

  function downloadBlob(blob, filename) {
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = filename;
    a.click();
    setTimeout(() => URL.revokeObjectURL(a.href), 5000);
  }

  // FEA-012 (2026-05-07): RFC 4180-ish CSV cell encoder. Goal — open in Excel /
  // pandas / R without surprise. null/undefined → empty cell, bool → 1/0,
  // numbers as-is, strings quoted only if they contain , " or newline,
  // objects/arrays as compact JSON inside a quoted cell.
  function csvCell(v) {
    if (v === null || v === undefined) return '';
    if (typeof v === 'boolean') return v ? '1' : '0';
    if (typeof v === 'number') return Number.isFinite(v) ? String(v) : '';
    if (typeof v === 'object') {
      return '"' + JSON.stringify(v).replace(/"/g, '""') + '"';
    }
    const s = String(v);
    return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  }

  // Stable column order: behavioral-analysis-friendly fields up front, then the
  // rest alphabetised so files from the same task sit identical for diffing.
  const PRIMARY_KEYS = [
    'stimulus_onset_ms', 'response_ms', 'rt',
    'response', '_correct', 'responded',
  ];
  const orderedKeys = (() => {
    const head = PRIMARY_KEYS.filter(k => allKeys.includes(k));
    const rest = allKeys.filter(k => !head.includes(k)).sort();
    return [...head, ...rest];
  })();

  function exportCSV() {
    if (!trials || !trials.length) return;
    // CSV-friendly task params summary (single-line JSON in header comment).
    const paramsSummary = params ? JSON.stringify(params) : '';
    const headerMeta = [
      `# subject_name=${subject.name || ''}`,
      `# subject_birthdate=${subject.birthdate || ''}`,
      `# subject_age=${subject.age || ''}`,
      `# subject_gender=${subject.gender || ''}`,
      `# test_date=${subject.testDate || ''}`,
      `# test=${quest.name}`,
      `# task_id=${quest.id != null ? quest.id : ''}`,
      `# domain=${quest.domain || ''}`,
      `# difficulty=${quest.dl || ''}`,
      `# n_trials=${trials.length}`,
      `# task_params=${paramsSummary}`,
      `# exported_at=${new Date().toISOString()}`,
      `# schema_version=1`,
    ];
    const rows = [
      ...headerMeta,
      ['trial_index', ...orderedKeys].join(','),
    ];
    trials.forEach((tr, i) => {
      rows.push([i, ...orderedKeys.map(k => csvCell(tr[k]))].join(','));
    });
    // BOM so Excel auto-detects UTF-8 (otherwise Chinese subject names mojibake).
    downloadBlob(
      new Blob(['﻿' + rows.join('\n')], { type: 'text/csv;charset=utf-8' }),
      `${fnameStem}.csv`,
    );
  }

  function exportJSON() {
    if (!trials || !trials.length) return;
    const payload = {
      schema_version: 1,
      exported_at: new Date().toISOString(),
      subject: {
        name:      subject.name      || null,
        birthdate: subject.birthdate || null,
        age:       subject.age != null && subject.age !== '' ? +subject.age : null,
        gender:    subject.gender    || null,
        test_date: subject.testDate  || null,
      },
      task: {
        id:         quest.id != null ? quest.id : null,
        name:       quest.name,
        domain:     quest.domain || null,
        difficulty: quest.dl     || null,
        params:     params       || null,
      },
      metrics: metrics || [],
      // trials carry per-trial stimulus details + responded/rt + stimulus_onset_ms
      // + response_ms (task-relative timestamps from test-runner.js).
      n_trials: trials.length,
      trials,
    };
    downloadBlob(
      new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json;charset=utf-8' }),
      `${fnameStem}.json`,
    );
  }

  return (
    <div className="paper-grain" style={{
      position:'fixed',inset:0,zIndex:300,
      background:'radial-gradient(ellipse at 50% 40%, #faf3e0, #ede0c2)',
      display:'flex',flexDirection:'column',alignItems:'center',
      justifyContent:'center',gap:'1.6rem',
      fontFamily:'var(--serif)',color:'var(--inkw)',
      overflowY:'auto',padding:'2rem 1rem',
    }}>
      {/* Title */}
      <div style={{textAlign:'center'}}>
        {subjectLine && (
          <div style={{
            fontSize:'.75rem', color:'var(--dim)', letterSpacing:'.08em',
            fontFamily:'var(--italic)', fontStyle:'italic', marginBottom:'.6rem',
          }}>{subjectLine}</div>
        )}
        <div style={{fontSize:'2rem',color:domainColor,lineHeight:1,marginBottom:'.4rem'}}>{quest.glyph}</div>
        <div style={{fontSize:'1.4rem',fontWeight:700,letterSpacing:'.06em'}}>{quest.name}</div>
        <div style={{
          display:'inline-block',marginTop:'.5rem',
          padding:'.2rem .75rem',
          border:`1px solid ${domainColor}`,color:domainColor,
          fontSize:'.72rem',letterSpacing:'.1em',fontFamily:'var(--italic)',fontStyle:'italic',
        }}>{quest.dl}</div>
      </div>

      {/* Metric cards */}
      <div style={{
        display:'grid',
        gridTemplateColumns:'repeat(auto-fit,minmax(200px,1fr))',
        gap:'1rem',width:'100%',maxWidth:760,
      }}>
        {(metrics||[]).map((m, i) => (
          <div key={i} style={{
            background:'var(--cream)',
            border:'1px solid var(--wcbdr)',
            borderTop:`3px solid ${domainColor}`,
            padding:'1rem 1.1rem .9rem',
            boxShadow:'0 3px 12px rgba(30,40,20,.1)',
          }}>
            <div style={{fontSize:'.72rem',color:'var(--dim)',letterSpacing:'.08em',textTransform:'uppercase',marginBottom:'.4rem'}}>
              {m.label}
            </div>
            <div style={{display:'flex',alignItems:'baseline',gap:'.35rem'}}>
              <span style={{fontSize:'1.8rem',fontWeight:700,color:domainColor,lineHeight:1}}>{m.value}</span>
              {m.unit && <span style={{fontSize:'.75rem',color:'var(--dim)'}}>{m.unit}</span>}
            </div>
            <div style={{marginTop:'.6rem',height:4,background:'var(--parch)',borderRadius:2,overflow:'hidden'}}>
              <div style={{height:'100%',width:`${Math.max(0,Math.min(100,m.pct||0))}%`,background:domainColor,borderRadius:2}}/>
            </div>
          </div>
        ))}
      </div>

      {/* Actions */}
      <div style={{display:'flex',gap:'.9rem',marginTop:'.5rem',flexWrap:'wrap',justifyContent:'center'}}>
        <button onClick={exportCSV} style={{
          background:'none',border:`1px solid var(--forest)`,color:'var(--forest)',
          fontFamily:'var(--serif)',fontSize:'.82rem',padding:'.5rem 1.2rem',cursor:'pointer',
          letterSpacing:'.06em',
        }}>匯出 CSV</button>
        <button onClick={exportJSON} style={{
          background:'none',border:`1px solid var(--forest)`,color:'var(--forest)',
          fontFamily:'var(--serif)',fontSize:'.82rem',padding:'.5rem 1.2rem',cursor:'pointer',
          letterSpacing:'.06em',
        }}>匯出 JSON（完整 raw）</button>
        <button onClick={onClose} style={{
          background:'linear-gradient(135deg,#d4931a,#f0c858)',border:'none',
          color:'#2c2416',fontFamily:'var(--serif)',fontWeight:700,
          fontSize:'.85rem',padding:'.55rem 1.8rem',cursor:'pointer',
          letterSpacing:'.08em',boxShadow:'0 2px 8px rgba(212,147,26,.4)',
        }}>返回庭園</button>
      </div>
    </div>
  );
}
window.ResultsOverlay = ResultsOverlay;
