import { useState } from "react";
import { Alert, Pressable, Text, View } from "react-native";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useLocalSearchParams } from "expo-router";
import { api } from "@/lib/api";
import { t } from "@/lib/i18n";
import { formatMinor } from "@/lib/money";
import {
  Body,
  Button,
  Card,
  EmptyState,
  ErrorView,
  Heading,
  Input,
  LoadingView,
  Row,
  Screen,
  Small,
  Spacer,
} from "@/components/ui";
import { colors, spacing } from "@/lib/theme";
import { formatQuantity } from "@/lib/units";

/** Inköpslista (spec §27): delad, avdelningssorterad, uppdaterar lagret vid avslut. */

interface ShoppingItem {
  id: string;
  displayName: string;
  quantity: number;
  unit: string;
  storeSection: string;
  estimatedPriceMinor: number | null;
  checked: boolean;
}
interface ListResponse {
  list: { id: string; name: string };
  items: ShoppingItem[];
  estimatedTotalMinor: number;
  currency: string;
}

/** Butikssektionernas etiketter bor i i18n-katalogen: shopping.section.<id> (12 språk). */
const SECTION_IDS = new Set([
  "frukt_gront",
  "brod",
  "mejeri",
  "kott_fagel",
  "fisk",
  "chark",
  "frys",
  "skafferi",
  "konserver",
  "kryddor_bak",
  "dryck",
  "snacks",
  "hygien_ovrigt",
]);
const sectionLabel = (id: string): string =>
  SECTION_IDS.has(id) ? t(`shopping.section.${id}`) : id;

export default function ShoppingScreen() {
  const queryClient = useQueryClient();
  const [newItem, setNewItem] = useState("");
  const params = useLocalSearchParams<{ listId?: string }>();
  const paramListId = typeof params.listId === "string" ? params.listId : undefined;

  const lists = useQuery({
    queryKey: ["shopping-lists"],
    queryFn: async () => {
      const result = await api<{ lists: Array<{ id: string }> }>("/v1/shopping-lists");
      if (result.lists.length === 0) {
        const created = await api<{ list: { id: string } }>("/v1/shopping-lists", {
          method: "POST",
          body: { name: t("shopping.title") },
        });
        return [created.list];
      }
      return result.lists;
    },
  });
  // Prioritera listId från navigering (t.ex. nygenererad från veckoplan),
  // annars nyaste aktiva listan.
  const listId = paramListId ?? lists.data?.[0]?.id;

  const list = useQuery({
    queryKey: ["shopping-list", listId],
    queryFn: () => api<ListResponse>(`/v1/shopping-lists/${listId}`),
    enabled: Boolean(listId),
  });

  const invalidate = () => {
    void queryClient.invalidateQueries({ queryKey: ["shopping-list", listId] });
    void queryClient.invalidateQueries({ queryKey: ["shopping-lists"] });
  };

  const addItem = useMutation({
    mutationFn: (displayName: string) =>
      api(`/v1/shopping-lists/${listId}/items`, { method: "POST", body: { displayName } }),
    onSuccess: () => {
      setNewItem("");
      invalidate();
    },
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  const toggle = useMutation({
    mutationFn: (item: ShoppingItem) =>
      api(`/v1/shopping-lists/${listId}/items/${item.id}`, {
        method: "PATCH",
        body: { checked: !item.checked },
      }),
    onSuccess: invalidate,
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  const remove = useMutation({
    mutationFn: (itemId: string) =>
      api(`/v1/shopping-lists/${listId}/items/${itemId}`, { method: "DELETE" }),
    onSuccess: invalidate,
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  const confirmRemove = (item: ShoppingItem) =>
    Alert.alert(item.displayName, "Ta bort varan från listan?", [
      { text: t("common.cancel"), style: "cancel" },
      { text: "Ta bort", style: "destructive", onPress: () => remove.mutate(item.id) },
    ]);

  const complete = useMutation({
    mutationFn: () =>
      api(`/v1/shopping-lists/${listId}/complete`, {
        method: "POST",
        body: { addToInventory: true },
      }),
    onSuccess: async (result) => {
      const added = (result as { itemsAddedToInventory?: number }).itemsAddedToInventory ?? 0;
      await queryClient.invalidateQueries({ queryKey: ["inventory"] });
      await queryClient.invalidateQueries({ queryKey: ["what-to-eat"] });
      invalidate();
      Alert.alert(t("shopping.completedTitle"), t("shopping.completedBody", { count: added }));
    },
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
  });

  if (lists.isLoading || list.isLoading) return <LoadingView />;
  if (list.isError || !list.data) return <ErrorView onRetry={() => void list.refetch()} />;

  const grouped = new Map<string, ShoppingItem[]>();
  for (const item of list.data.items) {
    const arr = grouped.get(item.storeSection) ?? [];
    arr.push(item);
    grouped.set(item.storeSection, arr);
  }
  const checkedCount = list.data.items.filter((i) => i.checked).length;

  return (
    <Screen>
      <Row>
        <View style={{ flex: 1 }}>
          <Input
            placeholder={t("shopping.addPlaceholder")}
            value={newItem}
            onChangeText={setNewItem}
            onSubmitEditing={() => newItem.trim() && addItem.mutate(newItem.trim())}
            returnKeyType="done"
          />
        </View>
        <Button label="+" onPress={() => newItem.trim() && addItem.mutate(newItem.trim())} />
      </Row>

      {list.data.items.length === 0 && <EmptyState text={t("shopping.empty")} />}

      {[...grouped.entries()].map(([section, items]) => (
        <Card key={section}>
          <Heading>{sectionLabel(section)}</Heading>
          {items.map((item) => (
            <Row
              key={item.id}
              style={{ justifyContent: "space-between", alignItems: "center", paddingVertical: 6 }}
            >
              <Pressable style={{ flex: 1 }} onPress={() => toggle.mutate(item)}>
                <Body>
                  <Text style={{ color: item.checked ? colors.primary : colors.textMuted }}>
                    {item.checked ? "☑" : "☐"}
                  </Text>{" "}
                  <Text
                    style={
                      item.checked
                        ? { textDecorationLine: "line-through", color: colors.textMuted }
                        : undefined
                    }
                  >
                    {item.displayName} · {formatQuantity(item.quantity, item.unit)}
                  </Text>
                </Body>
              </Pressable>
              {item.estimatedPriceMinor != null && (
                <Small>
                  {t("shopping.estimated", {
                    amount: formatMinor(item.estimatedPriceMinor, list.data.currency),
                  })}
                </Small>
              )}
              {/* Radera en vara man ångrat (utan att köpa den). */}
              <Pressable
                onPress={() => confirmRemove(item)}
                hitSlop={8}
                style={{ paddingHorizontal: spacing.sm }}
              >
                <Text style={{ color: colors.textMuted, fontSize: 18 }}>✕</Text>
              </Pressable>
            </Row>
          ))}
        </Card>
      ))}

      {list.data.estimatedTotalMinor > 0 && (
        <Small>
          {t("shopping.estimatedTotal", {
            amount: formatMinor(list.data.estimatedTotalMinor, list.data.currency),
          })}
        </Small>
      )}
      <Spacer size={spacing.sm} />
      {checkedCount > 0 && (
        <>
          <Button
            label={`${t("shopping.complete")} (${checkedCount})`}
            onPress={() => complete.mutate()}
            loading={complete.isPending}
          />
          <Small>{t("shopping.completeNote")}</Small>
        </>
      )}
    </Screen>
  );
}
