import { useMemo, useState } from 'react';
import { useRouter } from 'expo-router';
import { useMe, invalidateMe, type OnboardingStep } from '../../hooks/useMe';
import { apiFetch } from '../../lib/api';
import { WelcomeSlide } from '../../components/onboarding/slides/WelcomeSlide';
import { PrivacySlide } from '../../components/onboarding/slides/PrivacySlide';
import { NicknameSlide } from '../../components/onboarding/slides/NicknameSlide';
import { DigaChoiceSlide } from '../../components/onboarding/slides/DigaChoiceSlide';
import { DigaCodeSlide } from '../../components/onboarding/slides/DigaCodeSlide';
import { PlanSlide } from '../../components/onboarding/slides/PlanSlide';
import { PaymentSlide } from '../../components/onboarding/slides/PaymentSlide';
import { ProtectionSlide } from '../../components/onboarding/slides/ProtectionSlide';
import { DoneSlide } from '../../components/onboarding/slides/DoneSlide';
import { OnboardingNavProvider } from '../../components/onboarding/OnboardingNavContext';

/**
 * Duo-Style Onboarding — single route, state-machine intern.
 *
 *   Linear-Flow:
 *     [1] welcome      Lyra stellt sich vor
 *     [2] privacy      DSGVO-Versprechen
 *     [3] nickname     Inline-Input + PATCH /me + step='account'
 *     [4] diga_choice  "Hast du Rezept-Code?" Ja/Nein
 *           │
 *           ├─ Ja  → [4a] diga_code (Branch)
 *           │         redeem → step='pre_protection' → SKIP to [7]
 *           │
 *           └─ Nein →
 *     [5] plan         Pro/Legend selection → step='plan'
 *     [6] payment      DEV-Stub (RevenueCat-Phase pending) → step='pre_protection'
 *     [7] protection   activateUrlFilter() → step='done'
 *     [8] done         Geschafft-Screen → /(app)
 *
 *   Resume: routing-gate (app/(app)/_layout.tsx) routet zu /onboarding wenn
 *   step != 'done'. Hier mappt slideFromStep den persistierten step zur Slide.
 */
type Slide =
  | 'welcome'
  | 'privacy'
  | 'nickname'
  | 'diga_choice'
  | 'diga_code'
  | 'plan'
  | 'payment'
  | 'protection'
  | 'done';

// Linear-Order für Progress-Indicator + Default-Next-Navigation.
// diga_code ist NICHT in der Linear-Liste — wird via Branch erreicht.
const LINEAR_ORDER: Slide[] = [
  'welcome',
  'privacy',
  'nickname',
  'diga_choice',
  'plan',
  'payment',
  'protection',
  'done',
];

function slideFromStep(step: OnboardingStep): Slide {
  switch (step) {
    case 'welcome':
      return 'welcome';
    case 'account':
      return 'diga_choice';
    case 'plan':
      return 'payment';
    case 'pre_protection':
      return 'protection';
    case 'done':
      return 'done';
    case 'nickname': // legacy
      return 'nickname';
    case 'block': // legacy
      return 'protection';
    default:
      return 'welcome';
  }
}

export default function OnboardingScreen() {
  const router = useRouter();
  const { me } = useMe();
  const initialSlide = useMemo<Slide>(
    () => (me ? slideFromStep(me.onboardingStep) : 'welcome'),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [me?.id],
  );
  const [slide, setSlide] = useState<Slide>(initialSlide);

  function goToLinearNext() {
    const idx = LINEAR_ORDER.indexOf(slide);
    if (idx < 0 || idx === LINEAR_ORDER.length - 1) {
      router.replace('/(app)');
      return;
    }
    setSlide(LINEAR_ORDER[idx + 1]);
  }

  function goToLinearPrevious() {
    const idx = LINEAR_ORDER.indexOf(slide);
    if (idx <= 0) return;
    setSlide(LINEAR_ORDER[idx - 1]);
  }

  // Back erlaubt nur auf reinen Info-/Auswahl-Slides. NICHT auf:
  //   welcome (erste), done (final), diga_code (hat eigenen onBack),
  //   protection (interne Phasen + persistierter Backend-Step + Permission-Flow).
  const BACK_ALLOWED: Slide[] = ['privacy', 'nickname', 'diga_choice', 'plan', 'payment'];
  const canGoBack = BACK_ALLOWED.includes(slide);

  function exitToApp() {
    router.replace('/(app)');
  }

  // Branch-Handler ─────────────────────────────────────────────────────────────

  function onDigaYes() {
    setSlide('diga_code');
  }
  function onDigaNo() {
    setSlide('plan');
  }
  function onDigaCodeSuccess() {
    // Backend hat step='pre_protection' gesetzt → skip plan + payment
    setSlide('protection');
  }
  async function onPlanChosen(_tier: 'pro' | 'legend', _billing: 'monthly' | 'yearly') {
    // TODO: tier + billing an PaymentSlide weiterreichen sobald RevenueCat
    // wired ist (Phase 0). Bis dahin nur step persistieren.
    await apiFetch('/api/profile/me/onboarding-step', {
      method: 'PATCH',
      body: { step: 'plan' },
    }).catch(() => {});
    invalidateMe();
    setSlide('payment');
  }

  // Linear-Indizes für Progress (diga_code wird wie diga_choice gezählt) ──────

  const linearIdx = (() => {
    if (slide === 'diga_code') return LINEAR_ORDER.indexOf('diga_choice');
    return LINEAR_ORDER.indexOf(slide);
  })();
  const current = Math.max(1, linearIdx + 1);
  const total = LINEAR_ORDER.length;

  // Slide-Dispatch ────────────────────────────────────────────────────────────

  function renderSlide() {
    switch (slide) {
      case 'welcome':
        return <WelcomeSlide onNext={goToLinearNext} current={current} total={total} />;
      case 'privacy':
        return <PrivacySlide onNext={goToLinearNext} current={current} total={total} />;
      case 'nickname':
        return <NicknameSlide onNext={goToLinearNext} current={current} total={total} />;
      case 'diga_choice':
        return (
          <DigaChoiceSlide
            onYes={onDigaYes}
            onNo={onDigaNo}
            current={current}
            total={total}
          />
        );
      case 'diga_code':
        return (
          <DigaCodeSlide
            onSuccess={onDigaCodeSuccess}
            onBack={() => setSlide('diga_choice')}
            current={current}
            total={total}
          />
        );
      case 'plan':
        return <PlanSlide onChosen={onPlanChosen} current={current} total={total} />;
      case 'payment':
        return (
          <PaymentSlide onCompleted={goToLinearNext} current={current} total={total} />
        );
      case 'protection':
        return (
          <ProtectionSlide onDone={goToLinearNext} current={current} total={total} />
        );
      case 'done':
        return <DoneSlide onEnter={exitToApp} current={current} total={total} />;
    }
  }

  return (
    <OnboardingNavProvider goBack={canGoBack ? goToLinearPrevious : null}>
      {renderSlide()}
    </OnboardingNavProvider>
  );
}
