import { useEffect, useState } from "react";
import { Pressable, Text, View } from "react-native";
import { router } from "expo-router";
import { api } from "@/lib/api";
import { useAuth } from "@/lib/auth";
import { useAnalytics } from "@/lib/analytics";
import { t } from "@/lib/i18n";
import {
  onboardingStarted,
  onboardingStepCompleted,
  onboardingSkipped,
} from "@app/analytics";
import {
  Body,
  Button,
  Card,
  Heading,
  Input,
  Row,
  Screen,
  Small,
  Spacer,
  Title,
} from "@/components/ui";
import { colors, spacing, typography } from "@/lib/theme";

/**
 * Progressive onboarding (FAS 1b): 3-layer flow.
 * Step A = immediate value (goal + precision mode) – shown right after registration.
 * Step B = after first value (diet, allergens, household) – shown after first scan/cook.
 * Step C = contextual (health profile) – shown when user visits nutrition features.
 *
 * All steps are skippable (GDPR-friendly). Existing /v1/me/onboarding preserved
 * for backward compatibility.
 */

const GOALS = [
  "lose_weight",
  "build_muscle",
  "maintain_weight",
  "more_protein",
  "less_waste",
  "lower_cost",
  "cook_more",
] as const;

const DIETS = ["omnivore", "flexitarian", "pescatarian", "vegetarian", "vegan"] as const;

const ALLERGENS = [
  "gluten",
  "milk",
  "eggs",
  "tree_nuts",
  "peanuts",
  "fish",
  "crustaceans",
  "soy",
  "sesame",
] as const;

/** Which layer are we showing? */
type OnboardingLayer = "a" | "b" | "c";

export default function OnboardingScreen() {
  const setOnboardingCompleted = useAuth((s) => s.setOnboardingCompleted);
  const setOnboardingStep = useAuth((s) => s.setOnboardingStep);
  const savedStep = useAuth((s) => s.onboardingStep);
  const { track } = useAnalytics();
  const [layer, setLayer] = useState<OnboardingLayer>(savedStep ?? "a");

  useEffect(() => {
    track(onboardingStarted({ properties: { step: layer } }));
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  // Step A state
  const [goals, setGoals] = useState<string[]>([]);
  const [mode, setMode] = useState<"simple" | "exact">("simple");
  const primaryGoal = goals[0] ?? null;

  // Step B state
  const [diet, setDiet] = useState<string>("omnivore");
  const [allergens, setAllergens] = useState<string[]>([]);
  const [householdKind, setHouseholdKind] = useState<"create" | "join" | "skip">("create");
  const [householdName, setHouseholdName] = useState(t("onboarding.householdDefaultName"));
  const [inviteCode, setInviteCode] = useState("");

  // Step C state
  const [weightKg, setWeightKg] = useState("");
  const [heightCm, setHeightCm] = useState("");
  const [birthYear, setBirthYear] = useState("");

  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const toggleAllergen = (id: string) =>
    setAllergens((prev) => (prev.includes(id) ? prev.filter((a) => a !== id) : [...prev, id]));

  const toggleGoal = (id: string) =>
    setGoals((prev) => {
      if (prev.includes(id)) return prev.filter((g) => g !== id);
      // Keep the first-selected goal as primary by appending at the end.
      return [...prev, id];
    });

  const finishStepA = async () => {
    setBusy(true);
    setError(null);
    try {
      const res = await api<{ step: "a" | "b" | "c" }>("/v1/onboarding/quick-start", {
        method: "POST",
        body: {
          ...(goals.length ? { goals } : {}),
          precisionMode: mode,
        },
      });
      track(onboardingStepCompleted({ properties: { step: "a", goals, primaryGoal, precisionMode: mode } }));
      setOnboardingStep(res.step);
      setLayer("b");
      // Let user into the app – Step B will be shown contextually later
      router.replace("/(tabs)");
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  const finishStepB = async () => {
    setBusy(true);
    setError(null);
    try {
      const res = await api<{ step: "a" | "b" | "c" }>("/v1/onboarding/complete-b", {
        method: "POST",
        body: {
          precisionMode: mode,
          preferences: {
            dietPattern: diet,
            allergens,
          },
          householdChoice:
            householdKind === "create"
              ? { kind: "create", name: householdName || t("onboarding.householdDefaultName") }
              : householdKind === "join"
                ? { kind: "join", inviteCode }
                : { kind: "skip" },
        },
      });
      track(onboardingStepCompleted({ properties: { step: "b", diet, allergens, householdKind } }));
      setOnboardingStep(res.step);
      setLayer("c");
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  const finishStepC = async () => {
    setBusy(true);
    setError(null);
    try {
      track(onboardingStepCompleted({ properties: { step: "c" } }));
      await api("/v1/onboarding/complete-c", {
        method: "POST",
        body: {
          precisionMode: mode,
          healthProfile: {
            ...(weightKg ? { weightKg: Number(weightKg) } : {}),
            ...(heightCm ? { heightCm: Number(heightCm) } : {}),
            ...(birthYear ? { birthYear: Number(birthYear) } : {}),
          },
        },
      });
      setOnboardingCompleted(true);
      setOnboardingStep("c");
      router.replace("/(tabs)");
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  const skip = async (targetLayer?: OnboardingLayer) => {
    setBusy(true);
    try {
      track(onboardingSkipped({ properties: { step: targetLayer ?? layer } }));
      await api("/v1/onboarding/skip", {
        method: "POST",
        body: { step: targetLayer },
      });
      setOnboardingCompleted(true);
      setOnboardingStep("c");
      router.replace("/(tabs)");
    } catch (err) {
      setError(err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  // Render Step A: Immediate value
  if (layer === "a") {
    return (
      <Screen>
        <Title>{t("onboarding.title")}</Title>
        <Small>{t("onboarding.subtitle")}</Small>
        <Spacer size={spacing.sm} />

        <Heading>{t("onboarding.goal")}</Heading>
        <View style={{ gap: spacing.sm }}>
          {GOALS.map((id) => {
            const index = goals.indexOf(id);
            const selected = index >= 0;
            return (
              <SelectRow
                key={id}
                label={t(`onboarding.goal.${id}`)}
                selected={selected}
                onPress={() => toggleGoal(id)}
              >
                {selected && index === 0 && (
                  <View style={{ marginTop: 4 }}>
                    <Text style={[typography.small, { color: colors.primary, fontWeight: "600" }]}>
                      {t("onboarding.primaryGoal")}
                    </Text>
                  </View>
                )}
              </SelectRow>
            );
          })}
        </View>

        <Spacer size={spacing.sm} />
        <Heading>{t("onboarding.mode")}</Heading>
        <Card onPress={() => setMode("simple")} style={mode === "simple" ? sel : undefined}>
          <Body>{t("onboarding.modeSimple")}</Body>
          <Small>{t("onboarding.modeSimpleDesc")}</Small>
        </Card>
        <Card onPress={() => setMode("exact")} style={mode === "exact" ? sel : undefined}>
          <Body>{t("onboarding.modeExact")}</Body>
          <Small>{t("onboarding.modeExactDesc")}</Small>
        </Card>
        <Small>{t("onboarding.modesCombine")}</Small>

        {error && <Text style={{ color: colors.danger }}>{error}</Text>}
        <Spacer />
        <Row>
          <View style={{ flex: 1 }}>
            <Button label={t("common.skip")} variant="ghost" onPress={() => void skip("b")} />
          </View>
          <View style={{ flex: 2 }}>
            <Button label={t("common.next")} onPress={() => void finishStepA()} loading={busy} />
          </View>
        </Row>
        <Small>{t("onboarding.notMedical")}</Small>
      </Screen>
    );
  }

  // Render Step B: After first value
  if (layer === "b") {
    return (
      <Screen>
        <Title>{t("onboarding.stepBTitle")}</Title>
        <Small>{t("onboarding.stepBSubtitle")}</Small>
        <Spacer size={spacing.sm} />

        <Heading>{t("onboarding.diet")}</Heading>
        <Row>
          {DIETS.map((id) => (
            <Chip
              key={id}
              label={t(`onboarding.diet.${id}`)}
              selected={diet === id}
              onPress={() => setDiet(id)}
            />
          ))}
        </Row>

        <Spacer size={spacing.sm} />
        <Heading>{t("onboarding.allergies")}</Heading>
        <Row>
          {ALLERGENS.map((id) => (
            <Chip
              key={id}
              label={t(`onboarding.allergen.${id}`)}
              selected={allergens.includes(id)}
              onPress={() => toggleAllergen(id)}
            />
          ))}
        </Row>
        <Small>{t("onboarding.allergyNote")}</Small>

        <Spacer size={spacing.sm} />
        <Heading>{t("onboarding.household")}</Heading>
        <SelectRow
          label={t("onboarding.householdCreate")}
          selected={householdKind === "create"}
          onPress={() => setHouseholdKind("create")}
        />
        {householdKind === "create" && (
          <Input
            placeholder={t("onboarding.householdName")}
            value={householdName}
            onChangeText={setHouseholdName}
          />
        )}
        <SelectRow
          label={t("onboarding.householdJoin")}
          selected={householdKind === "join"}
          onPress={() => setHouseholdKind("join")}
        />
        {householdKind === "join" && (
          <Input
            placeholder={t("onboarding.inviteCode")}
            autoCapitalize="characters"
            value={inviteCode}
            onChangeText={setInviteCode}
          />
        )}
        <SelectRow
          label={t("common.skip")}
          selected={householdKind === "skip"}
          onPress={() => setHouseholdKind("skip")}
        />

        {error && <Text style={{ color: colors.danger }}>{error}</Text>}
        <Spacer />
        <Row>
          <View style={{ flex: 1 }}>
            <Button label={t("common.skip")} variant="ghost" onPress={() => void skip("c")} />
          </View>
          <View style={{ flex: 2 }}>
            <Button label={t("common.next")} onPress={() => void finishStepB()} loading={busy} />
          </View>
        </Row>
      </Screen>
    );
  }

  // Render Step C: Contextual (health profile)
  return (
    <Screen>
      <Title>{t("onboarding.stepCTitle")}</Title>
      <Small>{t("onboarding.stepCSubtitle")}</Small>
      <Spacer size={spacing.sm} />

      <Heading>{t("onboarding.bodyTitle")}</Heading>
      <Input
        placeholder={t("onboarding.weightPlaceholder")}
        keyboardType="numeric"
        value={weightKg}
        onChangeText={setWeightKg}
      />
      <Input
        placeholder={t("onboarding.heightPlaceholder")}
        keyboardType="numeric"
        value={heightCm}
        onChangeText={setHeightCm}
      />
      <Input
        placeholder={t("onboarding.birthYearPlaceholder")}
        keyboardType="numeric"
        value={birthYear}
        onChangeText={setBirthYear}
      />
      <Small>{t("onboarding.notMedical")}</Small>

      {error && <Text style={{ color: colors.danger }}>{error}</Text>}
      <Spacer />
      <Row>
        <View style={{ flex: 1 }}>
          <Button label={t("common.skip")} variant="ghost" onPress={() => void skip("c")} />
        </View>
        <View style={{ flex: 2 }}>
          <Button label={t("common.done")} onPress={() => void finishStepC()} loading={busy} />
        </View>
      </Row>
    </Screen>
  );
}

const sel = { borderColor: colors.primary, borderWidth: 2, backgroundColor: colors.primarySoft };

function SelectRow({
  label,
  selected,
  onPress,
  children,
}: {
  label: string;
  selected: boolean;
  onPress: () => void;
  children?: React.ReactNode;
}) {
  return (
    <Pressable
      onPress={onPress}
      style={{
        padding: spacing.md,
        borderRadius: 12,
        borderWidth: selected ? 2 : 1,
        borderColor: selected ? colors.primary : colors.border,
        backgroundColor: selected ? colors.primarySoft : colors.surface,
      }}
    >
      <Text style={{ color: colors.text, fontWeight: selected ? "700" : "400" }}>{label}</Text>
      {children}
    </Pressable>
  );
}

function Chip({
  label,
  selected,
  onPress,
}: {
  label: string;
  selected: boolean;
  onPress: () => void;
}) {
  return (
    <Pressable
      onPress={onPress}
      style={{
        paddingHorizontal: 14,
        paddingVertical: 8,
        borderRadius: 999,
        borderWidth: 1,
        borderColor: selected ? colors.primary : colors.border,
        backgroundColor: selected ? colors.primarySoft : colors.surface,
      }}
    >
      <Text style={{ color: selected ? colors.primaryDark : colors.textMuted, fontSize: 13 }}>
        {label}
      </Text>
    </Pressable>
  );
}
