
const { useState, useEffect, useRef } = React;

const API_BASE = 'https://transfer-lens.onrender.com';

const STEPS = [
  { id: 'cc',      label: 'Your College' },
  { id: 'term',    label: 'Timeline' },
  { id: 'schools', label: 'Target Schools' },
  { id: 'majors',  label: 'Majors' },
  { id: 'calgetc', label: 'Cal-GETC' },
  { id: 'ge',      label: 'GE Courses' },
  { id: 'review',  label: 'Review' },
];

const GE_AREAS = [
  {
    id: '1A',
    name: 'English Composition',
    description: 'Pick one course to satisfy Area 1A — English Composition.',
    pick: 1,
    courses: ['ENGL C1000', 'ENGL C1000H'],
  },
  {
    id: '1B',
    name: 'Critical Thinking',
    description: 'Pick one course to satisfy Area 1B — Critical Thinking.',
    pick: 1,
    courses: ['ENGL C1001', 'ENGL C1001H', 'LIB 20'],
  },
  {
    id: '1C',
    name: 'Oral Communication',
    description: 'Pick one course to satisfy Area 1C — Oral Communication.',
    pick: 1,
    courses: ['COMM C1000', 'COMM C1000H'],
  },
  {
    id: '3A',
    name: 'Arts',
    description: 'Pick one course to satisfy Area 3A — Arts.',
    pick: 1,
    courses: [
      'ART HIST 1', 'ART HIST 4', 'ART HIST 20',
      'DANCE 77', 'DANCE 78',
      'MUS 1', 'MUS 20', 'MUS 28',
      'THEATRE ARTS 20', 'THEATRE ARTS 21', 'THEATRE ARTS 22',
      'THEATRE ARTS 25', 'THEATRE ARTS 26', 'THEATRE ARTS 27',
    ],
  },
  {
    id: '3B',
    name: 'Humanities',
    description: 'Pick one course to satisfy Area 3B — Humanities.',
    pick: 1,
    courses: [
      'FILM 70', 'FILM 71', 'FILM 72',
      'FREN 2', 'FREN 3', 'FREN 4',
      'HIST 1', 'HIST 2', 'HIST 10', 'HIST 11', 'HIST 20', 'HIST 21',
      'JA 2', 'JA 3', 'JA 4',
      'LIT 1', 'LIT 7', 'LIT 16', 'LIT 20', 'LIT 21', 'LIT 22', 'LIT 23',
      'PHIL 1', 'PHIL 2', 'PHIL 10', 'PHIL 11',
      'SPAN 2', 'SPAN 3', 'SPAN 4',
    ],
  },
  {
    id: '4',
    name: 'Social & Behavioral Sciences',
    description: 'Pick 2 courses from 2 different disciplines to satisfy Area 4.',
    pick: 2,
    twoDisciplines: true,
    disciplines: {
      'Anthropology':      ['ANTHRO 2', 'ANTHRO 3', 'ANTHRO 4'],
      'Economics':         ['ECON 1', 'ECON 2'],
      'Geography':         ['GEOG 2', 'GEOG 3', 'GEOG 20'],
      'History':           ['HIST 1', 'HIST 2', 'HIST 20', 'HIST 21'],
      'Political Science': ['POLS C1000'],
      'Psychology':        ['PSYC C1000', 'PSYC 2', 'PSYC 5'],
      'Sociology':         ['SOCI 1', 'SOCI 2', 'SOCI 3'],
    },
  },
  {
    id: '5A',
    name: 'Physical Science',
    description: 'Pick one course to satisfy Area 5A — Physical Science.',
    pick: 1,
    courses: [
      'ASTRON 20', 'ASTRON 20H', 'ASTRON 25',
      'BIO 10',
      'CHEM 1A', 'CHEM 1AH', 'CHEM 1B', 'CHEM 3', 'CHEM 4', 'CHEM 12A', 'CHEM 12B',
      'EARTH SCI 20',
      'GEOG 1', 'GEOG 10', 'GEOG 10H',
      'GEOL 1', 'GEOL 2', 'GEOL 3', 'GEOL 22', 'GEOL 23',
      'MARINE SCI 20',
      'PHYS 2A', 'PHYS 2B', 'PHYS 4A', 'PHYS 4B', 'PHYS 4C', 'PHYS 20',
    ],
  },
  {
    id: '5B',
    name: 'Biological Science',
    description: 'Pick one course to satisfy Area 5B — Biological Science.',
    pick: 1,
    courses: [
      'ANTHRO 1', 'ANTHRO 1H',
      'BIO 1', 'BIO 2', 'BIO 3', 'BIO 5', 'BIO 11', 'BIO 12', 'BIO 15', 'BIO 16',
      'BIO 19', 'BIO 19H', 'BIO 21', 'BIO 30', 'BIO 43', 'BIO 44', 'BIO 55',
      'BIO 71', 'BIO 72', 'BIO 80', 'BIO 80H', 'BIO 81', 'BIO 81H', 'BIO 82', 'BIO 83',
      'BIOTECH 70',
      'PSYC 3', 'PSYC 3H',
    ],
  },
  {
    id: '6',
    name: 'Ethnic Studies',
    description: 'Pick one course to satisfy Area 6 — Ethnic Studies.',
    pick: 1,
    courses: ['ETHN 10', 'ETHN 20', 'ETHN 30', 'ETHN 40'],
  },
];

function StepDots({ current }) {
  return (
    <div className="wiz-dots">
      {STEPS.map((s, i) => (
        <div key={s.id} className={`wiz-dot-item ${i === current ? 'active' : ''} ${i < current ? 'done' : ''}`}>
          <div className="wiz-dot"></div>
        </div>
      ))}
      <div className="wiz-step-label">{current + 1} / {STEPS.length}</div>
    </div>
  );
}

/* ─── Step 1: Community College ─── */
function StepCC({ value, onChange }) {
  const [query, setQuery] = useState('');
  const inputRef = useRef(null);
  useEffect(() => { inputRef.current?.focus(); }, []);

  const filtered = query.length > 0
    ? window.MOCK_CCS.filter(c => c.name.toLowerCase().includes(query.toLowerCase()) || c.city.toLowerCase().includes(query.toLowerCase()))
    : window.MOCK_CCS;

  return (
    <div className="wiz-step">
      <div className="wiz-q">Which community college do you attend?</div>
      <div className="wiz-hint">We'll use this to look up your articulation agreements.</div>
      {value && (
        <div className="wiz-selected-banner">
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8l3.5 3.5L13 5" stroke="var(--green)" strokeWidth="2" strokeLinecap="round"/></svg>
          <span>{value.name}</span>
          <button className="wiz-selected-clear" onClick={() => onChange(null)}>Change</button>
        </div>
      )}
      {!value && (
        <div className="wiz-search-wrap">
          <svg className="wiz-search-icon" width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="6.5" cy="6.5" r="4" stroke="currentColor" strokeWidth="1.5"/><path d="M10 10l3 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
          <input ref={inputRef} className="wiz-search" placeholder="Search colleges…" value={query} onChange={e => setQuery(e.target.value)} />
        </div>
      )}
      {!value && (
        <div className="wiz-list">
          {filtered.map(cc => (
            <button key={cc.id} className={`wiz-list-item ${cc.id === 'ivc' ? 'default' : ''}`} onClick={() => onChange(cc)}>
              <div className="wiz-list-item-left">
                <div className="wiz-list-name">{cc.name}</div>
                <div className="wiz-list-sub">{cc.city}</div>
              </div>
              {cc.id === 'ivc' && <span className="wiz-default-badge">Default</span>}
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

/* ─── Step 2: Transfer Term ─── */
function StepTerm({ value, onChange }) {
  return (
    <div className="wiz-step">
      <div className="wiz-q">When do you plan to transfer?</div>
      <div className="wiz-hint">This determines how many semesters you have to complete your coursework.</div>
      <div className="wiz-term-grid">
        {window.TRANSFER_TERMS.map(t => (
          <button key={t.id} className={`wiz-term-btn ${value.term === t.id ? 'active' : ''}`} onClick={() => onChange({ ...value, term: t.id })}>
            {t.label}
          </button>
        ))}
      </div>
      <div className="wiz-divider"></div>
      <div className="wiz-q-small">Would you like to use summer semesters?</div>
      <div className="wiz-toggle-row">
        <button className={`wiz-toggle-btn ${value.useSummer ? 'active' : ''}`} onClick={() => onChange({ ...value, useSummer: true })}>Yes — I'm open to it</button>
        <button className={`wiz-toggle-btn ${!value.useSummer ? 'active' : ''}`} onClick={() => onChange({ ...value, useSummer: false })}>No, keep it to fall & spring</button>
      </div>
      <div className={`wiz-reveal ${value.useSummer ? 'wiz-reveal-open' : ''}`}>
        <div className="wiz-reveal-inner">
          <div className="wiz-q-small" style={{ marginTop: 20 }}>Summer load preference</div>
          <div className="wiz-toggle-row">
            <button className={`wiz-toggle-btn ${value.summerLoad === 'light' ? 'active' : ''}`} onClick={() => onChange({ ...value, summerLoad: 'light' })}>Light — 1 to 2 courses</button>
            <button className={`wiz-toggle-btn ${value.summerLoad === 'full' ? 'active' : ''}`} onClick={() => onChange({ ...value, summerLoad: 'full' })}>Full — 3 to 4 courses</button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ─── Step 3: Target Schools (API) ─── */
function StepSchools({ value, onChange }) {
  const [query, setQuery] = useState('');
  const [allSchools, setAllSchools] = useState({ UC: [], CSU: [] });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const inputRef = useRef(null);

  useEffect(() => { inputRef.current?.focus(); }, []);

  const loadSchools = () => {
    setLoading(true);
    setError(null);
    Promise.all([
      fetch(`${API_BASE}/api/institutions?category=UC`).then(r => r.ok ? r.json() : Promise.reject('UC fetch failed')),
      fetch(`${API_BASE}/api/institutions?category=CSU`).then(r => r.ok ? r.json() : Promise.reject('CSU fetch failed')),
    ]).then(([uc, csu]) => {
      const mapSchool = (s, type) => ({ id: s.id, name: s.name, abbr: s.code, type });
      setAllSchools({ UC: uc.map(s => mapSchool(s, 'UC')), CSU: csu.map(s => mapSchool(s, 'CSU')) });
      setLoading(false);
    }).catch(err => {
      setError(typeof err === 'string' ? err : 'Failed to load schools. Please check your connection.');
      setLoading(false);
    });
  };

  useEffect(() => { loadSchools(); }, []);

  const all = [...allSchools.UC, ...allSchools.CSU];
  const filtered = query.length > 1
    ? { UC: all.filter(s => s.type === 'UC' && (s.name.toLowerCase().includes(query.toLowerCase()) || s.abbr.toLowerCase().includes(query.toLowerCase()))),
        CSU: all.filter(s => s.type === 'CSU' && (s.name.toLowerCase().includes(query.toLowerCase()) || s.abbr.toLowerCase().includes(query.toLowerCase()))) }
    : allSchools;

  const toggle = (school) => {
    const exists = value.find(s => s.id === school.id);
    if (exists) onChange(value.filter(s => s.id !== school.id));
    else onChange([...value, school]);
  };

  return (
    <div className="wiz-step">
      <div className="wiz-q">Which schools are you applying to?</div>
      <div className="wiz-hint">Select all that apply — we'll find overlapping courses that satisfy multiple schools at once.</div>
      {value.length > 0 && (
        <div className="wiz-pills-row">
          {value.map(s => (
            <span key={s.id} className="wiz-pill-tag">
              {s.abbr}
              <button className="wiz-pill-remove" onClick={() => toggle(s)}>×</button>
            </span>
          ))}
        </div>
      )}
      <div className="wiz-search-wrap">
        <svg className="wiz-search-icon" width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="6.5" cy="6.5" r="4" stroke="currentColor" strokeWidth="1.5"/><path d="M10 10l3 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
        <input ref={inputRef} className="wiz-search" placeholder="Search schools…" value={query} onChange={e => setQuery(e.target.value)} />
      </div>
      {loading && <div style={{ padding: '24px', textAlign: 'center', color: 'var(--text-3)', fontSize: '0.9rem' }}>Loading schools…</div>}
      {error && (
        <div style={{ padding: '16px', textAlign: 'center' }}>
          <div style={{ color: 'var(--red)', marginBottom: 12, fontSize: '0.88rem' }}>{error}</div>
          <button className="wiz-nav-sm" onClick={loadSchools}>Retry</button>
        </div>
      )}
      {!loading && !error && (
        <div className="wiz-school-groups">
          {[['UC', 'UC System'], ['CSU', 'CSU System']].map(([type, label]) => {
            const list = (filtered[type] || []);
            if (!list.length) return null;
            return (
              <div key={type} className="wiz-school-group">
                <div className="wiz-school-group-label">{label}</div>
                {list.map(s => {
                  const selected = value.find(v => v.id === s.id);
                  return (
                    <button key={s.id} className={`wiz-list-item ${selected ? 'selected' : ''}`} onClick={() => toggle(s)}>
                      <div className="wiz-list-item-left">
                        <div className="wiz-list-name">{s.name}</div>
                      </div>
                      <div className={`wiz-check-box ${selected ? 'checked' : ''}`}>
                        {selected && <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 6l2.5 2.5L10 3" stroke="white" strokeWidth="1.8" strokeLinecap="round"/></svg>}
                      </div>
                    </button>
                  );
                })}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

/* ─── Step 4: Majors (API per school) ─── */
function MajorSearchSelect({ school, value, onChange }) {
  const [query, setQuery] = React.useState('');
  const [open, setOpen] = React.useState(false);
  const [majors, setMajors] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const ref = React.useRef(null);

  React.useEffect(() => {
    setLoading(true);
    fetch(`${API_BASE}/api/institutions/${school.id}/majors`)
      .then(r => r.ok ? r.json() : [])
      .then(data => { setMajors(Array.isArray(data) ? data : []); setLoading(false); })
      .catch(() => setLoading(false));
  }, [school.id]);

  const filtered = query
    ? majors.filter(m => m.label.toLowerCase().includes(query.toLowerCase()))
    : majors;

  React.useEffect(() => {
    function handleClick(e) {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    }
    document.addEventListener('mousedown', handleClick);
    return () => document.removeEventListener('mousedown', handleClick);
  }, []);

  const select = (m) => { onChange(m); setQuery(''); setOpen(false); };
  const displayValue = value?.label || '';

  return (
    <div ref={ref} style={{ flex: 1, position: 'relative' }}>
      <div
        style={{
          display: 'flex', alignItems: 'center',
          padding: '10px 14px', border: `1.5px solid ${open ? 'var(--accent)' : 'var(--divider)'}`,
          borderRadius: 'var(--radius)', background: 'var(--bg)', cursor: 'text',
          gap: 8, transition: 'border-color 0.15s',
        }}
        onClick={() => { if (!loading) setOpen(true); }}
      >
        <svg width="13" height="13" viewBox="0 0 13 13" fill="none" style={{ color: 'var(--text-3)', flexShrink: 0 }}>
          <circle cx="5.5" cy="5.5" r="3.5" stroke="currentColor" strokeWidth="1.4"/>
          <path d="M8.5 8.5l2.5 2.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/>
        </svg>
        <input
          style={{ flex: 1, border: 'none', background: 'transparent', fontFamily: 'var(--font)', fontSize: '0.9rem', color: 'var(--text)', outline: 'none' }}
          placeholder={loading ? 'Loading majors…' : (displayValue || '— Search a major —')}
          value={open ? query : displayValue}
          onChange={e => { setQuery(e.target.value); setOpen(true); }}
          onFocus={() => { if (!loading) { setOpen(true); setQuery(''); } }}
          readOnly={loading}
        />
        <span style={{ color: 'var(--text-3)', fontSize: '0.7rem', flexShrink: 0 }}>▾</span>
      </div>
      {open && !loading && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0, zIndex: 200,
          background: 'var(--bg)', border: '1px solid var(--divider)', borderRadius: 'var(--radius)',
          boxShadow: 'var(--shadow)', maxHeight: 240, overflowY: 'auto',
        }}>
          {filtered.length === 0 && (
            <div style={{ padding: '12px 14px', fontSize: '0.82rem', color: 'var(--text-3)' }}>No matches</div>
          )}
          {filtered.map(m => (
            <button key={m.id}
              style={{
                display: 'block', width: '100%', textAlign: 'left', padding: '10px 14px',
                border: 'none', background: value?.id === m.id ? 'var(--accent-bg)' : 'none',
                color: value?.id === m.id ? 'var(--accent)' : 'var(--text)',
                fontFamily: 'var(--font)', fontSize: '0.88rem', fontWeight: value?.id === m.id ? 600 : 400,
                cursor: 'pointer', transition: 'background 0.1s',
              }}
              onMouseEnter={e => { if (value?.id !== m.id) e.currentTarget.style.background = 'var(--surface)'; }}
              onMouseLeave={e => { if (value?.id !== m.id) e.currentTarget.style.background = 'none'; }}
              onClick={() => select(m)}
            >{m.label}</button>
          ))}
        </div>
      )}
    </div>
  );
}

function StepMajors({ schools, value, onChange }) {
  return (
    <div className="wiz-step">
      <div className="wiz-q">What do you want to study?</div>
      <div className="wiz-hint">Choose a major for each school. You can always change this later.</div>
      <div className="wiz-majors-list">
        {schools.map(school => (
          <div key={school.id} className="wiz-major-row">
            <div className="wiz-major-school">{school.abbr}</div>
            <MajorSearchSelect
              school={school}
              value={value[school.id] || null}
              onChange={m => onChange({ ...value, [school.id]: m })}
            />
          </div>
        ))}
      </div>
    </div>
  );
}

/* ─── Step 5: Cal-GETC ─── */
function StepCalGETC({ value, onChange }) {
  return (
    <div className="wiz-step">
      <div className="wiz-q">Cal-GETC or 7-Course Breadth?</div>
      <div className="wiz-hint">Cal-GETC is the California community college general education pattern. Your choice depends on your target schools.</div>
      <div className="wiz-getc-options">
        <button className={`wiz-getc-card ${value === 'full' ? 'active' : ''}`} onClick={() => onChange('full')}>
          <div className="wiz-getc-title">Full Cal-GETC</div>
          <div className="wiz-getc-sub">All 11 areas · Required for most CSU transfers and preferred by UC</div>
          <div className="wiz-getc-tag">Recommended for most students</div>
        </button>
        <button className={`wiz-getc-card ${value === 'breadth' ? 'active' : ''}`} onClick={() => onChange('breadth')}>
          <div className="wiz-getc-title">7-Course Breadth</div>
          <div className="wiz-getc-sub">Minimum UC requirement · 7 courses across 3 subject areas</div>
          <div className="wiz-getc-tag">UC minimum only</div>
        </button>
      </div>
    </div>
  );
}

/* ─── Step 6: GE Course Selection ─── */
function StepGE({ value, onChange }) {
  const [idx, setIdx] = useState(0);
  const area = GE_AREAS[idx];
  const current = value[area.id] || [];

  const getDisciplineOf = (key) => {
    if (!area.twoDisciplines) return null;
    for (const [disc, courses] of Object.entries(area.disciplines)) {
      if (courses.includes(key)) return disc;
    }
    return null;
  };

  const selectedDisciplines = current.map(getDisciplineOf).filter(Boolean);

  const toggleCourse = (courseKey) => {
    const selected = current.includes(courseKey);
    if (selected) {
      onChange({ ...value, [area.id]: current.filter(k => k !== courseKey) });
      return;
    }
    if (area.twoDisciplines) {
      if (current.length >= 2) return;
      const disc = getDisciplineOf(courseKey);
      if (selectedDisciplines.includes(disc)) return;
      onChange({ ...value, [area.id]: [...current, courseKey] });
    } else {
      onChange({ ...value, [area.id]: [courseKey] });
    }
  };

  const isCourseDisabled = (courseKey) => {
    if (current.includes(courseKey)) return false;
    if (area.twoDisciplines) {
      if (current.length >= 2) return true;
      const disc = getDisciplineOf(courseKey);
      return selectedDisciplines.includes(disc);
    }
    return false;
  };

  const renderCourseItem = (courseKey) => {
    const selected = current.includes(courseKey);
    const disabled = isCourseDisabled(courseKey);
    return (
      <button
        key={courseKey}
        className={`wiz-list-item ${selected ? 'selected' : ''}`}
        style={{ opacity: disabled ? 0.38 : 1, cursor: disabled ? 'not-allowed' : 'pointer' }}
        onClick={() => !disabled && toggleCourse(courseKey)}
      >
        <div className="wiz-list-item-left">
          <div className="wiz-list-name">{courseKey}</div>
        </div>
        <div className={`wiz-check-box ${selected ? 'checked' : ''}`}>
          {selected && <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2 6l2.5 2.5L10 3" stroke="white" strokeWidth="1.8" strokeLinecap="round"/></svg>}
        </div>
      </button>
    );
  };

  return (
    <div className="wiz-step">
      <div className="wiz-progress-sub">Area {idx + 1} of {GE_AREAS.length}</div>
      <div className="wiz-q">Area {area.id} — {area.name}</div>
      <div className="wiz-hint">{area.description}{area.twoDisciplines ? ` (${current.length}/2 selected)` : ''}</div>
      <div className="wiz-school-groups" style={{ marginTop: 16 }}>
        {area.twoDisciplines
          ? Object.entries(area.disciplines).map(([disc, courses]) => (
              <div key={disc} className="wiz-school-group">
                <div className="wiz-school-group-label">{disc}</div>
                {courses.map(renderCourseItem)}
              </div>
            ))
          : <div className="wiz-school-group">
              {area.courses.map(renderCourseItem)}
            </div>
        }
      </div>
      <div className="wiz-choice-nav">
        <button className="wiz-nav-sm" disabled={idx === 0} onClick={() => setIdx(i => i - 1)}>← Prev</button>
        <div className="wiz-mini-dots">
          {GE_AREAS.map((a, i) => (
            <span
              key={i}
              className={`wiz-mini-dot ${i === idx ? 'active' : ''} ${(value[GE_AREAS[i].id] || []).length > 0 ? 'done' : ''}`}
              onClick={() => setIdx(i)}
            ></span>
          ))}
        </div>
        <button className="wiz-nav-sm" disabled={idx === GE_AREAS.length - 1} onClick={() => setIdx(i => i + 1)}>Next →</button>
      </div>
    </div>
  );
}

/* ─── Step 7: Review ─── */
function StepReview({ state }) {
  const { cc, term, schools, majors, calgetcMode, geSelections, useSummer } = state;
  const termLabel = (window.TRANSFER_TERMS.find(t => t.id === term) || {}).label || term;
  const geAreasDone = GE_AREAS.filter(a => (geSelections[a.id] || []).length > 0).length;
  const geCourseCount = Object.values(geSelections).reduce((sum, sel) => sum + (sel?.length || 0), 0);
  return (
    <div className="wiz-step">
      <div className="wiz-q">You're all set — let's build your plan.</div>
      <div className="wiz-hint">Here's a summary of what we'll use. You can change anything inside the plan builder.</div>
      <div className="wiz-review-card">
        <div className="wiz-review-row"><span className="wiz-review-label">Community College</span><span className="wiz-review-val">{cc?.name || 'Not set'}</span></div>
        <div className="wiz-review-row"><span className="wiz-review-label">Transfer Term</span><span className="wiz-review-val">{termLabel}</span></div>
        <div className="wiz-review-row"><span className="wiz-review-label">Summer Semesters</span><span className="wiz-review-val">{useSummer ? 'Yes' : 'No'}</span></div>
        <div className="wiz-review-row">
          <span className="wiz-review-label">Target Schools</span>
          <span className="wiz-review-val">
            {schools.length === 0 ? 'None selected' : schools.map(s => s.abbr).join(', ')}
          </span>
        </div>
        <div className="wiz-review-row">
          <span className="wiz-review-label">Majors</span>
          <div className="wiz-review-majors">
            {schools.map(s => (
              <div key={s.id} className="wiz-review-major-row">
                <span className="wiz-review-school-tag">{s.abbr}</span>
                <span className="wiz-review-major-name">{majors[s.id]?.label || 'Not set'}</span>
              </div>
            ))}
          </div>
        </div>
        <div className="wiz-review-row"><span className="wiz-review-label">Cal-GETC Pattern</span><span className="wiz-review-val">{calgetcMode === 'full' ? 'Full Cal-GETC (11 areas)' : '7-Course Breadth'}</span></div>
        <div className="wiz-review-row"><span className="wiz-review-label">GE Courses</span><span className="wiz-review-val">{geCourseCount} courses · {geAreasDone} of {GE_AREAS.length} areas</span></div>
      </div>
      <div className="wiz-review-note">
        The smart scheduler will place your courses in the ideal order based on prerequisites, unit caps, and difficulty balance.
      </div>
    </div>
  );
}

/* ─── Wizard Shell ─── */
function Wizard({ onComplete }) {
  const [step, setStep] = useState(0);
  const [animDir, setAnimDir] = useState(1);
  const [animating, setAnimating] = useState(false);

  const [cc, setCC] = useState(window.MOCK_CCS[0]);
  const [termState, setTermState] = useState({ term: 'fall-2027', useSummer: false, summerLoad: 'light' });
  const [schools, setSchools] = useState([]);
  const [majors, setMajors] = useState({});
  const [calgetcMode, setCalgetcMode] = useState('full');
  const [geSelections, setGeSelections] = useState({});

  const canNext = () => {
    if (step === 0) return !!cc;
    if (step === 2) return schools.length > 0;
    if (step === 3) return schools.every(s => !!majors[s.id]);
    return true;
  };

  const go = (dir) => {
    if (animating) return;
    const next = step + dir;
    if (next < 0 || next >= STEPS.length) return;
    setAnimDir(dir);
    setAnimating(true);
    setTimeout(() => {
      setStep(next);
      setAnimating(false);
    }, 180);
  };

  const generate = () => {
    onComplete({
      cc,
      ...termState,
      selections: schools.map(s => ({ school: s, major: majors[s.id] || null })),
      calgetcMode,
      geSelections,
    });
  };

  const stepState = { cc, term: termState.term, schools, majors, calgetcMode, geSelections, useSummer: termState.useSummer };

  const steps = [
    <StepCC key="cc" value={cc} onChange={setCC} />,
    <StepTerm key="term" value={termState} onChange={setTermState} />,
    <StepSchools key="schools" value={schools} onChange={setSchools} />,
    <StepMajors key="majors" schools={schools} value={majors} onChange={setMajors} />,
    <StepCalGETC key="calgetc" value={calgetcMode} onChange={setCalgetcMode} />,
    <StepGE key="ge" value={geSelections} onChange={setGeSelections} />,
    <StepReview key="review" state={stepState} />,
  ];

  return (
    <div className="wizard-overlay">
      <div className="wizard-inner">
        <StepDots current={step} />
        <div className={`wizard-body ${animating ? (animDir > 0 ? 'wiz-out-left' : 'wiz-out-right') : 'wiz-in'}`}>
          {steps[step]}
        </div>
        <div className="wizard-nav">
          <button className="wiz-back-btn" onClick={() => go(-1)} disabled={step === 0}>
            ← Back
          </button>
          <div className="wiz-nav-right">
            {step < STEPS.length - 1 ? (
              <button className={`wiz-next-btn ${!canNext() ? 'disabled' : ''}`} onClick={() => canNext() && go(1)}>
                Continue →
              </button>
            ) : (
              <button className="wiz-generate-btn" onClick={generate}>
                ✦ Generate My Plan
              </button>
            )}
            {canNext() && step < STEPS.length - 1 && (
              <div className="wiz-enter-hint">press Enter to continue</div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Wizard });
