/* @file: question-view.jsx — Exposes: window.__app.QuestionView
 * Depends: window.__app.useStateMachine, window.__app.useKeyDown,
 *          window.__app.useHashRoute, window.__app.QUESTIONS,
 *          window.__app.QuestionText, window.__app.PhotoCycle,
 *          window.__portrait (from dot-engine.js)
 */
(() => {
  const ns = (window.__app = window.__app || {});

  function QuestionView({ id }) {
    const { useStateMachine, useKeyDown, useHashRoute, QUESTIONS, QuestionText, PhotoCycle } = ns;

    const { state, send } = useStateMachine();
    const { setHash } = useHashRoute();

    const question = QUESTIONS && QUESTIONS[id - 1];

    React.useEffect(() => {
      if (!question) setHash('/');
    }, [question, setHash]);

    // Expose current question metadata for downstream components (PhotoCycle reads these)
    React.useEffect(() => {
      if (!question) return undefined;
      ns.currentQuestionId = id;
      ns.currentQuestionLabel = question.label || '';
      const palette = question.scene && question.scene.palette;
      const watercolor = palette && palette.watercolor;
      const colors = Array.isArray(watercolor) && watercolor.length
        ? watercolor.map((b) => (b && (b.color || b))).filter((c) => typeof c === 'string')
        : [(palette && palette.ink) || '#2a2520'];
      ns.currentScenePalette = colors.length ? colors : ['#2a2520'];
      return () => {
        delete ns.currentQuestionId;
        delete ns.currentQuestionLabel;
        delete ns.currentScenePalette;
      };
    }, [id, question]);

    React.useEffect(() => {
      if (!question) return undefined;

      if (!window.__portrait) {
        console.error('[QuestionView] window.__portrait is undefined; redirecting to idle');
        setHash('/');
        return undefined;
      }

      let cancelled = false;
      send('navigate');
      send('sceneStart');

      Promise.resolve(window.__portrait.playScene(question.scene))
        .then(() => {
          if (!cancelled) send('sceneComplete');
        })
        .catch((err) => {
          if (cancelled) return; // expected: clearScene rejected the promise
          console.error('[QuestionView] playScene failed', err);
        });

      return () => {
        cancelled = true;
        if (window.__portrait && typeof window.__portrait.clearScene === 'function') {
          window.__portrait.clearScene();
        }
      };
    }, [id]);

    const handleEnter = React.useCallback(() => {
      if (!question || !window.__portrait) return;
      send('enterPressed');
      Promise.resolve(window.__portrait.morphToText(question.answer))
        .then(() => send('morphComplete'))
        .catch((err) => {
          console.error('[QuestionView] morphToText failed', err);
        });
    }, [question, send]);

    useKeyDown('Enter', handleEnter, { when: state === 'question-text' });

    const handleCycleComplete = React.useCallback(() => {
      send('photoCycleComplete');
      const nextId = id + 1;
      if (QUESTIONS && QUESTIONS[nextId - 1]) {
        setHash('/question/' + nextId);
      } else {
        setHash('/');
      }
    }, [id, send, setHash]);

    if (!question) return null;

    return (
      <>
        <QuestionText text={question.question} visible={state === 'question-text'} />
        {state === 'photo-cycle' && (
           <PhotoCycle media={question.media} onComplete={handleCycleComplete} />
        )}
      </>
    );
  }

  ns.QuestionView = QuestionView;
})();
