/* global React, SUBJECTS, I */

const { useState: obUseState, useEffect: obUseEffect, useMemo: obUseMemo, useRef: obUseRef } = React;

/**
 * Onboarding — 6 short steps, smoothly animated.
 * Steps: Welcome -> Year -> School -> Subjects -> Target grades -> Study time
 * Output: { year, school, subjects: [id...], targets: { id: 'A'|'B'... }, studyTime: { mon: minutes, ..., perDay: number } }
 */
function Onboarding({ onComplete }) {
  const STEPS = ['welcome', 'year', 'school', 'subjects', 'targets', 'time'];
  const [stepIdx, setStepIdx] = obUseState(0);
  const [direction, setDirection] = obUseState(1); // 1 = forward, -1 = back

  const [profile, setProfile] = obUseState(() => ({
    name: '',
    year: '12',
    school: '',
    subjects: ['maths', 'physics', 'english', 'legal', 'business', 'economics'],
    targets: {},
    studyTime: {
      currentMin: 60,                  // current study time per day (minutes)
      perDay: 120,                     // target average minutes/day
      customize: false,
      week: { mon: 120, tue: 120, wed: 120, thu: 120, fri: 90, sat: 60, sun: 60 },
    },
  }));

  const update = (patch) => setProfile(p => ({ ...p, ...patch }));
  const updateTime = (patch) => setProfile(p => ({ ...p, studyTime: { ...p.studyTime, ...patch } }));
  const updateWeek = (patch) => setProfile(p => ({ ...p, studyTime: { ...p.studyTime, week: { ...p.studyTime.week, ...patch } } }));

  const next = () => {
    if (stepIdx < STEPS.length - 1) { setDirection(1); setStepIdx(stepIdx + 1); }
    else finish();
  };
  const back = () => {
    if (stepIdx > 0) { setDirection(-1); setStepIdx(stepIdx - 1); }
  };
  const finish = () => {
    try { localStorage.setItem('lynxe-profile', JSON.stringify({ ...profile, completed: true, completedAt: new Date().toISOString() })); }
    catch {}
    onComplete && onComplete(profile);
  };

  // Keyboard: Enter advances, Esc goes back
  obUseEffect(() => {
    const onKey = (e) => {
      if (e.key === 'Enter' && !e.shiftKey && (e.target.tagName !== 'TEXTAREA')) {
        // Don't auto-advance from text input on welcome
        if (canAdvance()) next();
      } else if (e.key === 'Escape' && stepIdx > 0) back();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  });

  const canAdvance = () => {
    const s = STEPS[stepIdx];
    if (s === 'subjects') return profile.subjects.length > 0;
    return true;
  };

  const step = STEPS[stepIdx];

  return (
    <div className="ob-root">
      {/* Ambient gradient */}
      <div className="ob-gradient" />

      {/* Top bar: brand + progress + skip */}
      <div className="ob-top">
        <div className="ob-brand">
          <div className="ob-mark"><div className="ob-mark-l">L</div></div>
          <div className="ob-brand-name">Lynxe</div>
        </div>
        <div className="ob-progress">
          {STEPS.map((s, i) => (
            <div key={s} className={`ob-pip ${i <= stepIdx ? 'on' : ''} ${i === stepIdx ? 'now' : ''}`} />
          ))}
        </div>
        {stepIdx < STEPS.length - 1 && stepIdx > 0 ? (
          <button className="ob-skip" onClick={finish}>Skip setup</button>
        ) : <div style={{ width: 80 }} />}
      </div>

      {/* Stage */}
      <div className="ob-stage">
        <div
          key={step}
          className={`ob-step ob-anim-${direction > 0 ? 'fwd' : 'back'}`}
        >
          {step === 'welcome' && <StepWelcome profile={profile} update={update} />}
          {step === 'year' && <StepYear profile={profile} update={update} />}
          {step === 'school' && <StepSchool profile={profile} update={update} />}
          {step === 'subjects' && <StepSubjects profile={profile} update={update} />}
          {step === 'targets' && <StepTargets profile={profile} update={update} />}
          {step === 'time' && <StepTime profile={profile} updateTime={updateTime} updateWeek={updateWeek} />}
        </div>
      </div>

      {/* Footer nav */}
      <div className="ob-nav">
        <button className="btn ghost ob-back" onClick={back} disabled={stepIdx === 0} style={{ visibility: stepIdx === 0 ? 'hidden' : 'visible' }}>
          <I.ArrowLeft size={11} /> Back
        </button>
        <div className="ob-nav-sub dim">
          {stepIdx + 1} of {STEPS.length}
        </div>
        <button
          className="btn primary ob-next"
          onClick={next}
          disabled={!canAdvance()}
        >
          {stepIdx === STEPS.length - 1 ? 'Enter Lynxe' : 'Continue'}
          <I.ArrowRight size={11} />
        </button>
      </div>
    </div>
  );
}

/* ============== STEPS ============== */

function StepWelcome({ profile, update }) {
  return (
    <div className="ob-content ob-welcome">
      <div className="ob-eyebrow">Welcome</div>
      <h1 className="ob-h1">Let's set up your study system.</h1>
      <p className="ob-sub">
        A few quick questions so Lynxe can build a roadmap that fits your subjects, your targets, and your week.
        Takes about a minute.
      </p>
      <div className="ob-input-row" style={{ marginTop: 28 }}>
        <label className="ob-label">What should we call you?</label>
        <input
          className="ob-input"
          autoFocus
          placeholder="Your first name"
          value={profile.name}
          onChange={(e) => update({ name: e.target.value })}
        />
      </div>
    </div>
  );
}

function StepYear({ profile, update }) {
  const years = [
    { v: '7',  label: 'Year 7' },
    { v: '8',  label: 'Year 8' },
    { v: '9',  label: 'Year 9' },
    { v: '10', label: 'Year 10' },
    { v: '11', label: 'Year 11' },
    { v: '12', label: 'Year 12' },
  ];
  return (
    <div className="ob-content">
      <div className="ob-eyebrow">Step 2</div>
      <h1 className="ob-h1">{profile.name ? `Hi ${profile.name}, what year are you in?` : 'What year are you in?'}</h1>
      <p className="ob-sub">We'll align your roadmap with your year's curriculum.</p>
      <div className="ob-grid ob-grid-3" style={{ marginTop: 24 }}>
        {years.map((y, i) => (
          <button
            key={y.v}
            className={`ob-tile ${profile.year === y.v ? 'is-on' : ''}`}
            style={{ '--i': i }}
            onClick={() => update({ year: y.v })}
          >
            <div className="ob-tile-num">{y.v}</div>
            <div className="ob-tile-label">{y.label}</div>
          </button>
        ))}
      </div>
    </div>
  );
}

function StepSchool({ profile, update }) {
  return (
    <div className="ob-content">
      <div className="ob-eyebrow">Step 3 <span className="ob-eyebrow-opt">· optional</span></div>
      <h1 className="ob-h1">Which school do you go to?</h1>
      <p className="ob-sub">We use this to match school-specific resources and past papers. Skip if you'd rather not say.</p>
      <div className="ob-input-row" style={{ marginTop: 28, maxWidth: 480 }}>
        <input
          className="ob-input ob-input-lg"
          autoFocus
          placeholder="Search or type your school name"
          value={profile.school}
          onChange={(e) => update({ school: e.target.value })}
        />
        {profile.school && (
          <div className="dim ob-hint">We'll add specific resources for {profile.school}.</div>
        )}
      </div>
    </div>
  );
}

function StepSubjects({ profile, update }) {
  const [query, setQuery] = obUseState('');
  const visibleSet = new Set(profile.subjects);

  // Group subjects into categories
  const groups = obUseMemo(() => {
    const g = {
      'Mathematics': SUBJECTS.filter(s => s.id.startsWith('maths')),
      'English':     SUBJECTS.filter(s => s.id.startsWith('english')),
      'Sciences':    SUBJECTS.filter(s => ['physics','chemistry','biology','earth','investigating','sci-life','psychology'].includes(s.id)),
      'Humanities':  SUBJECTS.filter(s => ['legal','business','economics','modern-history','ancient-history','history-ext','geography','society','studies-religion-1','studies-religion-2','aboriginal'].includes(s.id)),
      'Languages':   SUBJECTS.filter(s => ['french','german','italian','spanish','japanese','chinese','korean','arabic','hindi','vietnamese','modern-greek','indonesian','latin','classical-greek'].includes(s.id)),
      'Creative Arts': SUBJECTS.filter(s => ['visual-arts','music-1','music-2','music-ext','drama','dance','photography'].includes(s.id)),
      'Technology':  SUBJECTS.filter(s => ['design-tech','industrial-tech','engineering','software','enterprise-comp','agriculture','food-tech','textiles'].includes(s.id)),
      'PDHPE':       SUBJECTS.filter(s => ['pdhpe','cafs','sls'].includes(s.id)),
    };
    if (!query) return g;
    const q = query.toLowerCase();
    const filtered = {};
    Object.keys(g).forEach(k => {
      const m = g[k].filter(s => s.name.toLowerCase().includes(q));
      if (m.length) filtered[k] = m;
    });
    return filtered;
  }, [query]);

  const toggle = (id) => {
    const set = new Set(profile.subjects);
    if (set.has(id)) set.delete(id); else set.add(id);
    update({ subjects: Array.from(set) });
  };

  return (
    <div className="ob-content ob-step-subjects">
      <div className="ob-eyebrow">Step 4</div>
      <h1 className="ob-h1">Which subjects are you taking?</h1>
      <p className="ob-sub">Pick everything you're studying this year. You can change these any time in Settings.</p>

      <div className="ob-input-row" style={{ marginTop: 18 }}>
        <div className="ob-search">
          <I.Search size={12} className="dim" />
          <input
            className="ob-search-input"
            placeholder="Search subjects…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
          />
          <span className="dim ob-count">
            {profile.subjects.length} selected
          </span>
        </div>
      </div>

      <div className="ob-subj-scroll">
        {Object.keys(groups).map(group => (
          <div key={group} className="ob-subj-group">
            <div className="ob-subj-grouphead">{group}</div>
            <div className="ob-subj-chips">
              {groups[group].map((s, i) => (
                <button
                  key={s.id}
                  className={`ob-chip ${visibleSet.has(s.id) ? 'is-on' : ''}`}
                  onClick={() => toggle(s.id)}
                  style={{ '--i': i, '--hex': s.hex }}
                >
                  <span className="ob-chip-dot" />
                  <span>{s.name}</span>
                  {visibleSet.has(s.id) && <I.Check size={10} strokeWidth={2.6} className="ob-chip-check" />}
                </button>
              ))}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function StepTargets({ profile, update }) {
  const grades = ['A', 'B', 'C', 'D', 'E'];
  const setTarget = (subjectId, grade) => {
    update({ targets: { ...profile.targets, [subjectId]: grade } });
  };

  // Auto-populate any missing targets to 'A'
  const get = (id) => profile.targets[id] || 'A';

  return (
    <div className="ob-content ob-step-targets">
      <div className="ob-eyebrow">Step 5</div>
      <h1 className="ob-h1">What grade are you aiming for?</h1>
      <p className="ob-sub">Set a target for each subject — we'll calibrate your study load to match.</p>

      <div className="ob-target-list">
        {profile.subjects.map((id, i) => {
          const subj = SUBJECTS.find(s => s.id === id);
          if (!subj) return null;
          return (
            <div key={id} className="ob-target-row" style={{ '--i': i }}>
              <span className="ob-target-dot" style={{ background: subj.hex }} />
              <span className="ob-target-name">{subj.name}</span>
              <div className="ob-target-grades">
                {grades.map(g => (
                  <button
                    key={g}
                    className={`ob-grade ${get(id) === g ? 'is-on' : ''}`}
                    onClick={() => setTarget(id, g)}
                  >{g}</button>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function StepTime({ profile, updateTime, updateWeek }) {
  const t = profile.studyTime;

  const fmt = (m) => {
    if (m === 0) return 'None';
    if (m < 60) return `${m}m`;
    const h = Math.floor(m / 60);
    const r = m % 60;
    return r ? `${h}h ${r}m` : `${h}h`;
  };

  const days = [
    ['mon', 'Mon'], ['tue', 'Tue'], ['wed', 'Wed'], ['thu', 'Thu'],
    ['fri', 'Fri'], ['sat', 'Sat'], ['sun', 'Sun'],
  ];

  const totalWeek = days.reduce((a, [k]) => a + t.week[k], 0);

  return (
    <div className="ob-content ob-step-time">
      <div className="ob-eyebrow">Step 6</div>
      <h1 className="ob-h1">How much can you study?</h1>
      <p className="ob-sub">Be honest — we'll build a roadmap that respects your time, not one that pretends you have more.</p>

      <div className="ob-time-card">
        <div className="ob-time-row">
          <div>
            <div className="ob-time-label">Currently studying</div>
            <div className="ob-time-sub dim">Roughly how much per day right now?</div>
          </div>
          <div className="ob-time-val">{fmt(t.currentMin)}</div>
        </div>
        <input
          type="range"
          min="0" max="360" step="15"
          className="ob-slider"
          value={t.currentMin}
          onChange={(e) => updateTime({ currentMin: parseInt(e.target.value, 10) })}
        />
        <div className="ob-slider-marks dim">
          <span>0</span><span>1h</span><span>2h</span><span>3h</span><span>4h</span><span>5h</span><span>6h</span>
        </div>
      </div>

      <div className="ob-time-card">
        <div className="ob-time-row">
          <div>
            <div className="ob-time-label">Target per day</div>
            <div className="ob-time-sub dim">How much can you commit to, on average?</div>
          </div>
          <div className="ob-time-val">{fmt(t.perDay)}</div>
        </div>
        <input
          type="range"
          min="15" max="360" step="15"
          className="ob-slider"
          value={t.perDay}
          onChange={(e) => {
            const v = parseInt(e.target.value, 10);
            updateTime({ perDay: v });
            // Mirror to week if not customized
            if (!t.customize) {
              updateWeek({ mon: v, tue: v, wed: v, thu: v, fri: v, sat: v, sun: v });
            }
          }}
        />
        <div className="ob-slider-marks dim">
          <span>15m</span><span>1h</span><span>2h</span><span>3h</span><span>4h</span><span>5h</span><span>6h</span>
        </div>

        <div className="ob-time-toggle">
          <label className="ob-checkbox">
            <input
              type="checkbox"
              checked={t.customize}
              onChange={(e) => updateTime({ customize: e.target.checked })}
            />
            <span className="ob-check-box">{t.customize && <I.Check size={9} strokeWidth={3} />}</span>
            <span className="ob-check-label">Customize per day of the week</span>
          </label>
        </div>

        {t.customize && (
          <div className="ob-week">
            {days.map(([k, label], i) => (
              <div key={k} className="ob-week-row" style={{ '--i': i }}>
                <span className="ob-week-day">{label}</span>
                <input
                  type="range"
                  min="0" max="360" step="15"
                  className="ob-slider ob-slider-sm"
                  value={t.week[k]}
                  onChange={(e) => updateWeek({ [k]: parseInt(e.target.value, 10) })}
                />
                <span className="ob-week-val tnum">{fmt(t.week[k])}</span>
              </div>
            ))}
            <div className="ob-week-total dim">
              <span>Weekly total</span>
              <span className="tnum">{fmt(totalWeek)}</span>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

window.Onboarding = Onboarding;
