// Top-level app: routing, state persistence, tweaks.

const { useState, useEffect, useMemo, useCallback } = React;

const TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{
  "showBrierScore": true,
  "shuffleQuestions": false,
  "accentMode": "teal",
  "fontScale": 1
}/*EDITMODE-END*/;

function App() {
  const { questions: rawQuestions, roundTitles, strings } = window.CALIBRATION_DATA;
  const helpers = window.CALIB_HELPERS;

  const [tweaks, setTweaks] = useState(TWEAKS_DEFAULTS);
  const [tweaksOpen, setTweaksOpen] = useState(false);

  // Load persisted state once.
  const [state, setState] = useState(() => {
    const saved = helpers.loadState();
    if (saved && saved.answers && Array.isArray(saved.answers)) {
      return {
        view: saved.view || 'intro',
        idx: saved.idx ?? 0,
        answers: saved.answers,
        order: saved.order || null,
      };
    }
    return { view: 'intro', idx: 0, answers: [], order: null };
  });

  // Question order — supports shuffling tweak.
  const order = state.order || rawQuestions.map((_, i) => i);
  const questions = useMemo(() => order.map((i) => rawQuestions[i]), [order]);

  useEffect(() => {
    helpers.saveState(state);
  }, [state]);

  const start = (fresh = true) => {
    let nextOrder = order;
    if (fresh && tweaks.shuffleQuestions) {
      // shuffle within rounds to keep round narrative
      const byRound = {};
      rawQuestions.forEach((q, i) => { (byRound[q.round] ||= []).push(i); });
      Object.values(byRound).forEach((arr) => {
        for (let i = arr.length - 1; i > 0; i--) {
          const j = Math.floor(Math.random() * (i + 1));
          [arr[i], arr[j]] = [arr[j], arr[i]];
        }
      });
      nextOrder = [1, 2, 3, 4].flatMap((r) => byRound[r] || []);
    } else if (fresh) {
      nextOrder = rawQuestions.map((_, i) => i);
    }
    setState({
      view: 'question',
      idx: 0,
      answers: fresh ? [] : state.answers,
      order: nextOrder,
    });
  };

  const resume = () => setState((s) => ({ ...s, view: 'question' }));

  const reset = () => {
    if (state.answers.some((a) => a) && !confirm(strings.nav.restartConfirm)) return;
    helpers.clearState();
    setState({ view: 'intro', idx: 0, answers: [], order: null });
  };

  const updateCurrent = (patch) => {
    setState((s) => {
      const answers = s.answers.slice();
      answers[s.idx] = { ...(answers[s.idx] || {}), ...patch, skipped: false };
      return { ...s, answers };
    });
  };

  const next = () => {
    setState((s) => {
      const isLast = s.idx >= questions.length - 1;
      return { ...s, view: isLast ? 'results' : 'question', idx: isLast ? s.idx : s.idx + 1 };
    });
  };

  const skip = () => {
    setState((s) => {
      const answers = s.answers.slice();
      answers[s.idx] = { skipped: true };
      const isLast = s.idx >= questions.length - 1;
      return { ...s, answers, view: isLast ? 'results' : 'question', idx: isLast ? s.idx : s.idx + 1 };
    });
  };

  const back = () => {
    setState((s) => ({ ...s, idx: Math.max(0, s.idx - 1) }));
  };

  // ----- Tweaks panel protocol -----
  useEffect(() => {
    const handler = (e) => {
      if (!e.data || typeof e.data !== 'object') return;
      if (e.data.type === '__activate_edit_mode') setTweaksOpen(true);
      if (e.data.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', handler);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', handler);
  }, []);

  const setTweak = (k, v) => {
    setTweaks((t) => {
      const next = { ...t, [k]: v };
      window.parent.postMessage({ type: '__edit_mode_set_keys', edits: { [k]: v } }, '*');
      return next;
    });
  };

  const closeTweaks = () => {
    setTweaksOpen(false);
    window.parent.postMessage({ type: '__edit_mode_dismissed' }, '*');
  };

  // Apply font scale + accent
  useEffect(() => {
    document.documentElement.style.setProperty('--font-scale', tweaks.fontScale);
    const accentMap = {
      teal: '14, 135, 156',
      ink: '27, 82, 102',
      peach: '235, 130, 60'
    };
    document.documentElement.style.setProperty('--accent-rgb', accentMap[tweaks.accentMode] || accentMap.teal);
    document.body.classList.toggle('hide-brier', !tweaks.showBrierScore);
  }, [tweaks]);

  const current = state.answers[state.idx];
  const answeredCount = state.answers.filter((a) => a && (a.picked || a.skipped)).length;

  return (
    <div className={`app view-${state.view}`} data-screen-label={`view-${state.view}`}>
      <window.AppHeader
        strings={strings}
        onRestart={reset}
        showRestart={state.view !== 'intro'}
      />

      {state.view === 'intro' && (
        <window.IntroScreen
          strings={strings}
          totalQuestions={questions.length}
          answeredCount={answeredCount}
          hasInProgress={answeredCount > 0 && state.idx < questions.length}
          onStart={() => start(true)}
          onResume={resume}
        />
      )}

      {state.view === 'question' && (
        <window.QuestionScreen
          strings={strings}
          roundTitles={roundTitles}
          questions={questions}
          idx={state.idx}
          current={current}
          onPick={(p) => updateCurrent({ picked: p })}
          onConfidence={(c) => updateCurrent({ confidence: c })}
          onNext={next}
          onSkip={skip}
          onBack={back}
        />
      )}

      {state.view === 'results' && (
        <window.ResultsScreen
          strings={strings}
          questions={questions}
          answers={state.answers}
          onRestart={reset}
        />
      )}

      <footer className="app-foot">
        <span>{strings.appTitle}</span>
        <span className="foot-sep">·</span>
        <span className="foot-en">{strings.appTitleEn}</span>
        <span className="foot-sep">·</span>
        <a href="https://eavn.org" target="_blank" rel="noopener" className="foot-link">eavn.org</a>
      </footer>

      {tweaksOpen && (
        <TweaksPanel tweaks={tweaks} setTweak={setTweak} onClose={closeTweaks} />
      )}
    </div>
  );
}

function TweaksPanel({ tweaks, setTweak, onClose }) {
  return (
    <div className="tweaks-panel" role="dialog" aria-label="Tweaks">
      <div className="tweaks-head">
        <span className="tweaks-title">Tweaks</span>
        <button className="tweaks-close" onClick={onClose} aria-label="Close">×</button>
      </div>

      <div className="tweaks-section">
        <label className="tweak-row">
          <span className="tweak-lbl">Hiển thị điểm Brier</span>
          <input
            type="checkbox"
            checked={!!tweaks.showBrierScore}
            onChange={(e) => setTweak('showBrierScore', e.target.checked)}
          />
        </label>
        <label className="tweak-row">
          <span className="tweak-lbl">Xáo trộn câu hỏi trong vòng</span>
          <input
            type="checkbox"
            checked={!!tweaks.shuffleQuestions}
            onChange={(e) => setTweak('shuffleQuestions', e.target.checked)}
          />
        </label>
      </div>

      <div className="tweaks-section">
        <div className="tweak-row tweak-radio">
          <span className="tweak-lbl">Tông màu</span>
          <div className="seg-radio">
            {[
              { v: 'teal', label: 'Teal' },
              { v: 'ink', label: 'Ink' },
              { v: 'peach', label: 'Peach' }
            ].map((o) => (
              <button
                key={o.v}
                className={`seg-radio-btn ${tweaks.accentMode === o.v ? 'on' : ''}`}
                onClick={() => setTweak('accentMode', o.v)}
              >{o.label}</button>
            ))}
          </div>
        </div>
        <div className="tweak-row">
          <span className="tweak-lbl">Cỡ chữ ({Math.round(tweaks.fontScale * 100)}%)</span>
          <input
            type="range"
            min="0.85" max="1.2" step="0.05"
            value={tweaks.fontScale}
            onChange={(e) => setTweak('fontScale', parseFloat(e.target.value))}
          />
        </div>
      </div>

      <p className="tweaks-foot">Thử nghiệm các biến thể nhỏ — không ảnh hưởng đến điểm số đã lưu.</p>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
