import { useEffect, useRef, useState } from "react";
import { Alert, Pressable, Text, View } from "react-native";
import { router, useLocalSearchParams } from "expo-router";
import { useKeepAwake } from "expo-keep-awake";
import * as Haptics from "expo-haptics";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { api } from "@/lib/api";
import { t } from "@/lib/i18n";
import {
  Body,
  Button,
  Card,
  ErrorView,
  Heading,
  LoadingView,
  Row,
  Screen,
  Small,
  Spacer,
} from "@/components/ui";
import { colors, spacing } from "@/lib/theme";

/**
 * Cooking Mode (spec §41): stora steg, stora knappar, skärmen vaken,
 * timers per steg, portionsskalning. Avslutas med "jag lagade detta"
 * som drar lager, loggar måltid och kan skapa matlådor (spec §23–24).
 */

interface RecipeForCooking {
  id: string;
  titleSv: string;
  portions: number;
  steps: Array<{
    id: string;
    stepNumber: number;
    instructionSv: string;
    timerSeconds: number | null;
    temperatureC: number | null;
    tip: string | null;
  }>;
}

export default function CookingScreen() {
  useKeepAwake();
  const { id, portions: portionsParam } = useLocalSearchParams<{ id: string; portions?: string }>();
  const queryClient = useQueryClient();
  const [stepIndex, setStepIndex] = useState(0);
  const [timerLeft, setTimerLeft] = useState<number | null>(null);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const [finishing, setFinishing] = useState(false);
  const [completedSessionId, setCompletedSessionId] = useState<string | null>(null);
  const [mealBoxPortions, setMealBoxPortions] = useState(0);
  const [actualPortionsEaten, setActualPortionsEaten] = useState<number | null>(null);
  const [leftoverEstimatePortions, setLeftoverEstimatePortions] = useState<number | null>(null);

  const query = useQuery({
    queryKey: ["recipe", id],
    queryFn: () => api<RecipeForCooking>(`/v1/recipes/${id}`),
  });

  const cook = useMutation({
    mutationFn: (body: unknown) =>
      api<{
        sessionId: string;
        mealBoxMutations?: Array<{ mealBoxId: string; deltaPortions: number; frozen: boolean }>;
      }>(`/v1/recipes/${id}/cook`, { method: "POST", body }),
    onSuccess: async (data) => {
      await queryClient.invalidateQueries({ queryKey: ["inventory"] });
      await queryClient.invalidateQueries({ queryKey: ["day"] });
      await queryClient.invalidateQueries({ queryKey: ["what-to-eat"] });
      setCompletedSessionId(data.sessionId);
    },
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  const undo = useMutation({
    mutationFn: () => api(`/v1/cooking-sessions/${completedSessionId}/undo`, { method: "POST" }),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ["meal-boxes"] });
      await queryClient.invalidateQueries({ queryKey: ["inventory"] });
      await queryClient.invalidateQueries({ queryKey: ["day"] });
      Alert.alert(t("common.done"), t("mealbox.undoSuccess"));
      router.dismissAll();
    },
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  useEffect(() => {
    return () => {
      if (timerRef.current) clearInterval(timerRef.current);
    };
  }, []);

  if (query.isLoading) return <LoadingView />;
  if (query.isError || !query.data) return <ErrorView onRetry={() => void query.refetch()} />;
  const recipe = query.data;
  const portionsCooked = Number(portionsParam ?? recipe.portions) || recipe.portions;
  const step = recipe.steps[stepIndex];
  const isLast = stepIndex >= recipe.steps.length - 1;

  const startTimer = (seconds: number) => {
    if (timerRef.current) clearInterval(timerRef.current);
    setTimerLeft(seconds);
    timerRef.current = setInterval(() => {
      setTimerLeft((prev) => {
        if (prev == null || prev <= 1) {
          if (timerRef.current) clearInterval(timerRef.current);
          void Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
          return 0;
        }
        return prev - 1;
      });
    }, 1000);
  };

  const finish = () => {
    setFinishing(true);
  };

  if (completedSessionId) {
    return (
      <Screen>
        <Card>
          <Heading>✅ {t("cooked.title")}</Heading>
          <Body>{recipe.titleSv}</Body>
          <Small>
            {t("cooked.portionsCooked")}: {portionsCooked}
          </Small>
        </Card>
        <Small>{t("mealbox.guidanceNote")}</Small>
        <Button
          label={t("common.undo")}
          variant="secondary"
          loading={undo.isPending}
          onPress={() =>
            Alert.alert(t("mealbox.undoConfirmTitle"), t("mealbox.undoConfirmBody"), [
              { text: t("common.cancel"), style: "cancel" },
              { text: t("common.undo"), style: "destructive", onPress: () => undo.mutate() },
            ])
          }
        />
        <Button label={t("common.done")} onPress={() => router.dismissAll()} />
      </Screen>
    );
  }

  if (finishing) {
    const defaultEaten = actualPortionsEaten ?? Math.max(0, portionsCooked - mealBoxPortions);
    const defaultLeftovers = leftoverEstimatePortions ?? mealBoxPortions;

    return (
      <Screen>
        <Heading>{t("cooked.title")}</Heading>
        <Card>
          <Body>{recipe.titleSv}</Body>
          <Small>
            {t("cooked.portionsCooked")}: {portionsCooked}
          </Small>
        </Card>
        <Card>
          <Row style={{ justifyContent: "space-between" }}>
            <Body>🍱 {t("cooked.mealBoxes")}</Body>
            <Row>
              <Button
                label="−"
                variant="ghost"
                onPress={() => setMealBoxPortions(Math.max(0, mealBoxPortions - 1))}
              />
              <Body>{mealBoxPortions}</Body>
              <Button
                label="+"
                variant="ghost"
                onPress={() => setMealBoxPortions(Math.min(portionsCooked, mealBoxPortions + 1))}
              />
            </Row>
          </Row>
        </Card>
        <Card>
          <Body>{t("cooked.actualPortionsEaten")}</Body>
          <Row>
            <Button
              label="−"
              variant="ghost"
              onPress={() => setActualPortionsEaten(Math.max(0, defaultEaten - 1))}
            />
            <Body>{defaultEaten}</Body>
            <Button
              label="+"
              variant="ghost"
              onPress={() => setActualPortionsEaten(Math.min(portionsCooked, defaultEaten + 1))}
            />
          </Row>
          <Small>{t("cooked.actualPortionsEatenHint")}</Small>
        </Card>
        <Card>
          <Body>{t("cooked.leftoverEstimatePortions")}</Body>
          <Row>
            <Button
              label="−"
              variant="ghost"
              onPress={() => setLeftoverEstimatePortions(Math.max(0, defaultLeftovers - 1))}
            />
            <Body>{defaultLeftovers}</Body>
            <Button
              label="+"
              variant="ghost"
              onPress={() =>
                setLeftoverEstimatePortions(
                  Math.min(portionsCooked - defaultEaten, defaultLeftovers + 1),
                )
              }
            />
          </Row>
          <Small>{t("cooked.leftoverEstimateHint")}</Small>
        </Card>
        <Small>{t("cooked.deductPantryNote")}</Small>
        <Spacer size={spacing.sm} />
        <Button
          label={t("cooking.finish")}
          loading={cook.isPending}
          onPress={() =>
            cook.mutate({
              portionsCooked,
              mealBoxPortions,
              actualPortionsEaten: actualPortionsEaten ?? defaultEaten,
              leftoverEstimatePortions: leftoverEstimatePortions ?? defaultLeftovers,
              mealBoxFrozen: false,
              deductInventory: true,
              mealType: "dinner",
            })
          }
        />
        <Button
          label={t("common.skip")}
          variant="ghost"
          onPress={() =>
            cook.mutate({
              portionsCooked,
              mealBoxPortions,
              actualPortionsEaten: defaultEaten,
              leftoverEstimatePortions: defaultLeftovers,
              mealBoxFrozen: false,
              deductInventory: true,
              mealType: "dinner",
            })
          }
        />
        <Button label={t("common.back")} variant="ghost" onPress={() => setFinishing(false)} />
      </Screen>
    );
  }

  return (
    <Screen scroll={false} style={{ justifyContent: "space-between" }}>
      <View style={{ gap: spacing.md }}>
        <Small>{recipe.titleSv}</Small>
        <Heading>
          {t("cooking.step", { current: stepIndex + 1, total: recipe.steps.length })}
        </Heading>
        <Text style={{ fontSize: 24, lineHeight: 34, color: colors.text }}>
          {step?.instructionSv}
          {step?.temperatureC ? `  (${step.temperatureC} °C)` : ""}
        </Text>
        {step?.tip && <Small>💡 {step.tip}</Small>}

        {step?.timerSeconds != null && (
          <Pressable
            onPress={() => startTimer(step.timerSeconds!)}
            style={{
              backgroundColor: timerLeft != null ? colors.accentSoft : colors.primarySoft,
              padding: spacing.lg,
              borderRadius: 16,
              alignItems: "center",
            }}
          >
            <Text style={{ fontSize: 32, fontWeight: "700", color: colors.primaryDark }}>
              {timerLeft != null ? formatTime(timerLeft) : formatTime(step.timerSeconds)}
            </Text>
            <Small>
              {timerLeft != null
                ? timerLeft === 0
                  ? `${t("cooking.timerDone")} 🎉`
                  : t("cooking.timerRunning", { time: formatTime(timerLeft) })
                : t("cooking.timer")}
            </Small>
          </Pressable>
        )}
        <Small>{t("cooking.keepAwake")}</Small>
      </View>

      <Row style={{ paddingBottom: spacing.lg }}>
        <View style={{ flex: 1 }}>
          <Button
            label={`← ${t("common.back")}`}
            variant="ghost"
            disabled={stepIndex === 0}
            onPress={() => setStepIndex(Math.max(0, stepIndex - 1))}
          />
        </View>
        <View style={{ flex: 2 }}>
          <Button
            label={isLast ? t("cooking.finish") : `${t("common.next")} →`}
            onPress={() => (isLast ? finish() : setStepIndex(stepIndex + 1))}
          />
        </View>
      </Row>
    </Screen>
  );
}

function formatTime(totalSeconds: number): string {
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;
  return `${minutes}:${String(seconds).padStart(2, "0")}`;
}
