// Memoriz onboarding — App orchestrator

// Flow steps (the 5 spec'd screens + splash + loading + success)
// 0 splash, 1 goal, 2 family, 3 moment, 4 loading, 5 plan reveal, 6 paywall, 7 success
const TOTAL = 5;
const PROGRESS_INDEX = { 1: 0, 2: 1, 3: 2, 5: 3, 6: 4 };

const App = () => {
  const [step, setStep] = useState(0);
  const [direction, setDirection] = useState('forward');
  const [goal, setGoal] = useState(null);
  const [circle, setCircle] = useState([]);
  const [moment, setMoment] = useState(null);

  const effectiveGoal = goal || 'family';
  const effectiveCircle = circle.length ? circle : ['partner', 'mom', 'grandma'];
  const effectiveMoment = moment || 'photo';

  const go = (next) => {
    setDirection(next > step ? 'forward' : 'back');
    setStep(next);
  };

  // For sliding transitions, we keep the current screen + the previous (briefly) in DOM
  const [renderedStep, setRenderedStep] = useState(step);
  const [prevStep, setPrevStep] = useState(null);
  const [phase, setPhase] = useState('idle'); // 'transition' | 'idle'

  useEffect(() => {
    if (step !== renderedStep) {
      setPrevStep(renderedStep);
      setRenderedStep(step);
      setPhase('transition');
      const t = setTimeout(() => {
        setPrevStep(null);
        setPhase('idle');
      }, 420);
      return () => clearTimeout(t);
    }
  }, [step]);

  // When phase becomes 'transition', we render both prevStep (outgoing) and renderedStep (incoming).
  // The incoming starts with 'slide-enter-r' (off-screen) and gets '.in' on next tick to animate.
  const [incomingActive, setIncomingActive] = useState(false);
  useEffect(() => {
    if (phase === 'transition') {
      setIncomingActive(false);
      const id = requestAnimationFrame(() => setIncomingActive(true));
      return () => cancelAnimationFrame(id);
    } else {
      setIncomingActive(false);
    }
  }, [phase, renderedStep]);

  return (
    <div className="stage">
      <div className="phone">
        <div className="phone-notch" />
        <div className="phone-inner">
          <div className="screen-stack">
            {/* outgoing */}
            {phase === 'transition' && prevStep !== null && (
              <div key={'out-' + prevStep}
                   className={'screen-layer ' + (direction === 'forward' ? 'slide-exit-l out' : 'slide-exit-r out')}
                   style={{ position: 'absolute', inset: 0 }}>
                {renderScreenInner(prevStep, {
                  goal, circle, moment, effectiveGoal, effectiveCircle, effectiveMoment,
                  setGoal, setCircle, setMoment, go,
                })}
              </div>
            )}
            {/* incoming / current */}
            <div key={'cur-' + renderedStep}
                 className={'screen-layer ' + (
                    phase === 'transition'
                      ? (direction === 'forward' ? 'slide-enter-r' : 'slide-enter-l') + (incomingActive ? ' in' : '')
                      : ''
                 )}
                 style={{ position: 'absolute', inset: 0 }}>
              {renderScreenInner(renderedStep, {
                goal, circle, moment, effectiveGoal, effectiveCircle, effectiveMoment,
                setGoal, setCircle, setMoment, go,
              })}
            </div>
          </div>
        </div>
      </div>

    </div>
  );
};

// Helper: a single render fn that takes step + state context, returns the screen JSX
function renderScreenInner(s, ctx) {
  const { goal, circle, moment, effectiveGoal, effectiveCircle, effectiveMoment,
          setGoal, setCircle, setMoment, go } = ctx;
  switch (s) {
    case 0: return <SplashScreen onStart={() => go(1)} />;
    case 1: return <ScreenGoal
      step={PROGRESS_INDEX[1]} total={TOTAL}
      value={goal}
      onSelect={(id) => { setGoal(id); go(2); }}
      onBack={() => go(0)} />;
    case 2: return <ScreenFamily
      step={PROGRESS_INDEX[2]} total={TOTAL}
      value={circle}
      onContinue={(ids) => { setCircle(ids); go(3); }}
      onBack={() => go(1)} />;
    case 3: return <ScreenMoment
      step={PROGRESS_INDEX[3]} total={TOTAL}
      value={moment}
      onSelect={(id) => { setMoment(id); go(4); }}
      onBack={() => go(2)} />;
    case 4: return <LoadingScreen
      goal={effectiveGoal} circle={effectiveCircle} moment={effectiveMoment}
      onDone={() => go(5)} />;
    case 5: return <ScreenPlanReveal
      step={PROGRESS_INDEX[5]} total={TOTAL}
      goal={effectiveGoal} circle={effectiveCircle} moment={effectiveMoment}
      onContinue={() => go(6)}
      onBack={() => go(3)} />;
    case 6: return <ScreenPaywall
      step={PROGRESS_INDEX[6]} total={TOTAL}
      goal={effectiveGoal}
      onBack={() => go(5)}
      onPay={() => go(7)}
      onMaybeLater={() => go(7)} />;
    case 7: return <SuccessScreen
      goal={effectiveGoal} moment={effectiveMoment}
      onReplay={() => { setGoal(null); setCircle([]); setMoment(null); go(0); }} />;
    default: return null;
  }
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
