/* ENSSA Reporting — Class page (Level 3). */

/* global React, Card, Eyebrow, KPI, Section, Btn, CSVExportButton,
   RiskBadge, StatusBadge, MoreInfoFlag,
   TaskBoxPlotPanel, RiskPyramid, TaskPercentileBar,
   RiskTransitionSankey, useMediaQuery,
   RISK, RISK_COPY, STATUS, TASK_DEFS, TERM_DEFAULT,
   riskCountsOf, statusCountsOf, taskBoxStats, TASKS, TEACHING_NOTE,
   getBattery, getMultiStageTransitions */

/* Battery-specific box stats for one class */
function taskBoxStatsForBattery(students, battery) {
  const stats = {};
  for (const t of battery) {
    const vals = students
      .filter(s => s.tasksDone === s.tasksTotal)
      .map(s => s.tp[t.id])
      .sort((a, b) => a - b);
    const insuff = students.length - vals.length;
    if (!vals.length) {
      stats[t.id] = { ...t, p10: 0, p25: 0, p50: 0, p75: 0, p90: 0, n: 0, insufficient: insuff, below20: 0 };
      continue;
    }
    const q = (p) => vals[Math.max(0, Math.min(vals.length - 1, Math.floor(p / 100 * vals.length)))];
    stats[t.id] = {
      ...t,
      p10: q(10), p25: q(25), p50: q(50), p75: q(75), p90: q(90),
      n: vals.length, insufficient: insuff,
      below20: vals.filter(v => v < 20).length,
    };
  }
  return stats;
}

/* ── Info icon + tooltip for section headings ── */
function InfoTitle({ title, tip }) {
  const [show, setShow] = React.useState(false);
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
      {title}
      <span style={{ position: 'relative', display: 'inline-flex', alignItems: 'center' }}
        onMouseEnter={() => setShow(true)}
        onMouseLeave={() => setShow(false)}
        onClick={() => setShow(v => !v)}>
        <span style={{
          width: 18, height: 18, borderRadius: '50%',
          background: 'var(--ink-200)', color: 'var(--fg-2)',
          fontSize: 11, fontWeight: 700, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          userSelect: 'none', flexShrink: 0,
        }}>i</span>
        {show && (
          <span style={{
            position: 'absolute', left: '50%', bottom: 'calc(100% + 8px)',
            transform: 'translateX(-50%)',
            background: 'var(--ink-800)', color: '#fff',
            fontSize: 12, lineHeight: 1.55, fontWeight: 400,
            padding: '10px 14px', borderRadius: 8,
            width: 280, boxShadow: 'var(--sh-3)',
            pointerEvents: 'none', zIndex: 99,
            textTransform: 'none', letterSpacing: 0,
          }}>
            {tip}
            <span style={{ position: 'absolute', left: '50%', bottom: -5, transform: 'translateX(-50%)', width: 10, height: 10, background: 'var(--ink-800)', clipPath: 'polygon(0 0, 100% 0, 50% 100%)' }} />
          </span>
        )}
      </span>
    </span>
  );
}

const { useState: useCS, useMemo } = React;

function ClassPage({ school, klass, onOpenStudent, term }) {
  const battery = getBattery(klass.year, klass.cohort || 'A', term || TERM_DEFAULT);
  const cn = { students: klass.students };
  const counts = riskCountsOf(cn);
  const status = statusCountsOf(cn);
  const stats = taskBoxStatsForBattery(klass.students, battery);
  const rec = computeRecommendation(counts, status);
  const transitions = getMultiStageTransitions(cn);

  return (
    <>
      <ScreeningCompletionCard status={status} klass={klass} school={school} />

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(360px, 1fr))', gap: 18, marginBottom: 32 }}>
        <Card>
          <Eyebrow>Class at a glance</Eyebrow>
          <h2 style={{ fontSize: 18, fontWeight: 700, margin: '4px 0 16px' }}>Screener Results</h2>
          <RiskPyramid counts={counts} />
        </Card>
        <RecommendationCard rec={rec} completionPct={Math.round(status.completed / (status.total || 1) * 100)} />
      </div>

      <Section title="Class performance by task">
        <Card><TaskBoxPlotPanel stats={stats} /></Card>
      </Section>

      <Section title="Risk-band movement across terms"
        hint="How this class's students moved between risk bands across screening windows.">
        <Card><RiskTransitionSankey transitions={transitions} classId={klass.id} /></Card>
      </Section>

      <Section title={<InfoTitle title="Per-student results" tip="Screening results are a signal, not a diagnosis. Use them alongside classroom evidence and teacher judgement." />}
        hint="Click a row to expand task scores inline, or open the full report.">
        <Card style={{ padding: 0, overflow: 'hidden' }}>
          <StudentTable students={klass.students} school={school} onOpenStudent={onOpenStudent} />
        </Card>
      </Section>
    </>);

}

/* ── Screening completion card ── */
function ScreeningCompletionCard({ status, klass, school }) {
  const tasksCompleted = klass.students.reduce((a, s) => a + s.tasksDone, 0);
  const tasksMax = klass.students.length * TASKS.length;
  const taskPct = Math.round(tasksCompleted / tasksMax * 100);
  const studentPct = Math.round(status.completed / (status.total || 1) * 100);

  return (
    <Card style={{ marginBottom: 24 }}>
      <div style={{ marginBottom: 16 }}>
        <Eyebrow>Screening completion</Eyebrow>
        <h2 style={{ fontSize: 18, fontWeight: 700, margin: '4px 0 0' }}>
          {status.completed} of {status.total} students fully completed <span style={{ color: 'var(--fg-3)', fontWeight: 400 }}>({studentPct}%)</span>
        </h2>
      </div>
      <div style={{ display: 'flex', gap: 24, marginBottom: 14, flexWrap: 'wrap' }}>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}><StatusBadge status="completed" /> <strong style={{ fontFamily: 'var(--font-mono)' }}>{status.completed}</strong></div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}><StatusBadge status="partial" /> <strong style={{ fontFamily: 'var(--font-mono)' }}>{status.partial}</strong></div>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}><StatusBadge status="notstarted" /> <strong style={{ fontFamily: 'var(--font-mono)' }}>{status.notstarted}</strong></div>
      </div>
      {/* Task-level progress bar */}
      <div style={{ height: 12, background: 'var(--ink-100)', borderRadius: 999, overflow: 'hidden' }}>
        <div style={{ width: `${taskPct}%`, height: '100%', background: 'var(--risk-on-track)', borderRadius: 999, transition: 'width 0.4s' }} />
      </div>
      <div style={{ marginTop: 5, fontSize: 11, color: 'var(--fg-3)', fontFamily: 'var(--font-mono)' }}>
        {tasksCompleted} of {tasksMax} individual tasks completed across the class
      </div>
    </Card>);

}

/* ── Single high-level recommendation ── */
function RecommendationCard({ rec, completionPct }) {
  const incomplete = completionPct < 80;
  return (
    <Card>
      <Eyebrow>Class recommendation</Eyebrow>
      <h2 style={{ fontSize: 18, fontWeight: 700, margin: '4px 0 16px' }}>Suggested focus</h2>
      {incomplete ?
      <div style={{ padding: '14px 16px', background: 'var(--ink-50)', border: '1px dashed var(--ink-300)', borderRadius: 8, fontSize: 14, color: 'var(--fg-2)', lineHeight: 1.55 }}>
          <strong style={{ color: 'var(--fg-1)' }}>Finish screening first.</strong> A class recommendation is generated once most students have completed the screener ({completionPct}% complete so far).
        </div> :

      <div style={{ padding: '14px 16px', background: rec.tone === 'concern' ? 'var(--risk-concern-bg)' : rec.tone === 'emerging' ? 'var(--risk-emerging-bg)' : 'var(--risk-on-track-bg)', border: `1px solid ${rec.tone === 'concern' ? 'var(--risk-concern)' : rec.tone === 'emerging' ? 'var(--risk-emerging)' : 'var(--risk-on-track)'}`, borderRadius: 8, fontSize: 14, color: 'var(--fg-1)', lineHeight: 1.6 }}>
          {rec.text}
        </div>
      }
      <p style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 14, lineHeight: 1.5, paddingTop: 12, borderTop: '1px solid var(--border-subtle)' }}>
        Recommendation is based on the overall class shape and task profile. Pair with classroom evidence and teacher judgement.
      </p>
    </Card>);

}

function computeRecommendation(counts, status) {
  const total = counts.low + counts.moderate + counts.high || 1;
  const highPct = counts.high / total;
  const weakestTone = highPct > 0.25 ? 'concern' : counts.moderate > counts.low ? 'emerging' : 'neutral';
  let text;
  if (highPct > 0.25) {
    text = `More than a quarter of the class may benefit from targeted support. Plan structured small-group instruction focused on foundational number sense alongside whole-class Tier 1 teaching.`;
  } else if (counts.moderate > counts.low) {
    text = `Several students may benefit from additional support. Consider small-group teaching and monitor for movement in the next screening window.`;
  } else {
    text = `The class profile is broadly in the low-risk range. Continue Tier 1 instruction and monitor students in the moderate band.`;
  }
  return { tone: weakestTone, text };
}

/* ── Simple view selector replacing the old FilterPanel ── */
function ViewSelector({ value, onChange }) {
  const opts = [
    { id: 'all',       label: 'Show all' },
    { id: 'high',      label: 'High risk' },
    { id: 'moderate',  label: 'Moderate risk' },
    { id: 'low',       label: 'Low risk' },
    { id: 'incomplete',label: 'Incomplete' },
  ];
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 16px', borderBottom: '1px solid var(--border-subtle)', background: 'var(--ink-50)' }}>
      <span style={{ fontSize: 12, fontWeight: 700, color: 'var(--fg-3)', letterSpacing: '0.06em', textTransform: 'uppercase' }}>View</span>
      <select value={value} onChange={e => onChange(e.target.value)}
        style={{ fontFamily: 'inherit', fontSize: 13, fontWeight: 600, padding: '6px 12px', borderRadius: 7, border: '1px solid var(--border-default)', background: '#fff', color: 'var(--fg-1)', cursor: 'pointer' }}>
        {opts.map(o => <option key={o.id} value={o.id}>{o.label}</option>)}
      </select>
    </div>
  );
}

function StudentTable({ students, school, onOpenStudent }) {
  const isMobile = useMediaQuery('(max-width: 767px)');
  const [sortKey, setSortKey] = useCS('indexScore');
  const [asc, setAsc] = useCS(false);
  const [openId, setOpenId] = useCS(null);
  const [view, setView] = useCS('all');

  function getPercentile(s) {
    if (s.risk === 'more_info') return null;
    return s.overallPercentile; // always population (school/pop toggle removed)
  }

  const filtered = useMemo(() => students.filter(s => {
    if (view === 'high')       return s.risk === 'high';
    if (view === 'moderate')   return s.risk === 'moderate';
    if (view === 'low')        return s.risk === 'low';
    if (view === 'incomplete') return s.status !== 'completed';
    return true;
  }), [students, view]);

  const sorted = useMemo(() => {
    return [...filtered].sort((a, b) => {
      const av = a[sortKey], bv = b[sortKey];
      const cmp = typeof av === 'string' ? av.localeCompare(bv) : av - bv;
      return asc ? cmp : -cmp;
    });
  }, [filtered, sortKey, asc]);

  function header(key, label, align = 'left') {
    return (
      <th onClick={() => { if (sortKey === key) setAsc(!asc); else { setSortKey(key); setAsc(false); } }}
        style={{ textAlign: align, padding: '14px 16px', fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--fg-3)', fontWeight: 700, cursor: 'pointer', userSelect: 'none', borderBottom: '1px solid var(--border-subtle)', whiteSpace: 'nowrap' }}>
        {label}{sortKey === key ? (asc ? ' ↑' : ' ↓') : ''}
      </th>
    );
  }

  // Row click handler differs by viewport: mobile = navigate, desktop/tablet = expand.
  const handleRowClick = (s) => {
    if (isMobile) onOpenStudent(s.id);
    else setOpenId(openId === s.id ? null : s.id);
  };

  // colSpan for the inline "Task profile" expansion row.
  // Desktop+tablet: blank | Student | Band | Score | %ile | Tasks | Status | View → = 8 cells
  // First cell is the chevron, then we colSpan the remaining 7.
  const expandColSpan = 7;

  return (
    <div style={{ overflowX: 'auto' }}>
      <div style={{ padding: '10px 16px', borderBottom: '1px solid var(--border-subtle)', display: 'flex', alignItems: 'center', gap: 12, background: 'var(--ink-50)', flexWrap: 'wrap' }}>
        <ViewSelector value={view} onChange={setView} />
      </div>
      <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: isMobile ? 0 : 680 }}>
        <thead style={{ background: 'var(--ink-50)' }}>
          <tr>
            {!isMobile && <th style={{ width: 36, borderBottom: '1px solid var(--border-subtle)' }}></th>}
            {header('name', 'Student')}
            {isMobile ? (
              header('indexScore', 'Score', 'left')
            ) : (
              <>
                {header('risk', 'Band')}
                {header('indexScore', 'Score', 'right')}
              </>
            )}
            {header('overallPercentile', isMobile ? '%ile' : 'Population %ile', 'right')}
            {!isMobile && header('tasksDone', 'Tasks', 'right')}
            {header('status', 'Status')}
            <th style={{ borderBottom: '1px solid var(--border-subtle)' }}></th>
          </tr>
        </thead>
        <tbody>
          {sorted.map((s) => {
            const open = !isMobile && openId === s.id;
            return (
              <React.Fragment key={s.id}>
                <tr
                  style={{ borderBottom: '1px solid var(--border-subtle)', background: open ? 'var(--ink-50)' : 'transparent', cursor: 'pointer' }}
                  onClick={() => handleRowClick(s)}>
                  {!isMobile && (
                    <td style={{ padding: '12px 0 12px 16px', color: 'var(--fg-4)', fontSize: 12 }}>{open ? '▾' : '▸'}</td>
                  )}
                  <td style={{ padding: '14px 16px', fontWeight: 600 }}>{s.name}</td>
                  {isMobile ? (
                    <td style={{ padding: '12px 16px' }}>
                      <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 10, flexWrap: 'nowrap' }}>
                        <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, fontSize: 18, color: s.risk === 'more_info' ? 'var(--fg-3)' : 'var(--fg-1)', flexShrink: 0 }}>
                          {s.risk === 'more_info' ? '—' : s.indexScore}
                        </span>
                        <RiskBadge level={s.risk} size="sm" />
                      </div>
                    </td>
                  ) : (
                    <>
                      <td style={{ padding: '14px 16px' }}><RiskBadge level={s.risk} size="sm" /></td>
                      <td style={{ padding: '14px 16px', fontFamily: 'var(--font-mono)', textAlign: 'right', fontWeight: 700 }}>{s.risk === 'more_info' ? '—' : s.indexScore}</td>
                    </>
                  )}
                  <td style={{ padding: '14px 16px', fontFamily: 'var(--font-mono)', textAlign: 'right', color: 'var(--fg-2)' }}>{getPercentile(s) != null ? `P${getPercentile(s)}` : '—'}</td>
                  {!isMobile && (
                    <td style={{ padding: '14px 16px', fontFamily: 'var(--font-mono)', textAlign: 'right', color: s.tasksDone < s.tasksTotal ? 'var(--risk-emerging-fg)' : 'var(--fg-2)' }}>{s.tasksDone}/{s.tasksTotal}</td>
                  )}
                  <td style={{ padding: '14px 16px' }}><StatusBadge status={s.status} /></td>
                  <td style={{ padding: '14px 16px', textAlign: 'right' }}>
                    <button onClick={(e) => {e.stopPropagation();onOpenStudent(s.id);}}
                    style={{ background: 'none', border: 0, color: 'var(--accent)', cursor: 'pointer', fontFamily: 'inherit', fontWeight: 700, fontSize: 13, whiteSpace: 'nowrap' }}>
                      View →
                    </button>
                  </td>
                </tr>
                {open &&
                <tr style={{ background: 'var(--ink-50)', borderBottom: '2px solid var(--border-default)' }}>
                    <td></td>
                    <td colSpan={expandColSpan} style={{ padding: '14px 16px 22px' }}>
                      <Eyebrow style={{ marginBottom: 10 }}>Task profile</Eyebrow>
                      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 10 }}>
                        {(getBattery(s.year, s.cohort || 'A', TERM_DEFAULT)).map((t) => {
                        const p = s.tp[t.id];
                        return (
                          <div key={t.id} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                              <span style={{ fontSize: 13, fontWeight: 600, width: 130, color: 'var(--fg-1)', flexShrink: 0 }}>{t.label}</span>
                              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, fontWeight: 700, width: 34, color: p < 20 ? 'var(--risk-concern-fg)' : 'var(--fg-2)', flexShrink: 0 }}>P{p}</span>
                              <div style={{ flex: 1 }}><TaskPercentileBar value={p} /></div>
                            </div>);

                      })}
                      </div>
                    </td>
                  </tr>
                }
              </React.Fragment>);

          })}
        </tbody>
      </table>
    </div>);

}

window.ClassPage = ClassPage;