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

/**
 * Matlager: allt du har hemma, städat per plats (Kyl/Frys/Skafferi …).
 * Sök, filtrera på plats, markera flera och ta bort. Radering = mjuk
 * (kvantitet → 0, historik bevaras).
 */

interface InventoryItem {
  id: string;
  displayName: string;
  quantity: number;
  unit: string;
  locationName: string;
  locationType: string;
  expiry: { status: string; daysLeft: number | null; pastBestBefore: boolean };
}

const LOCATION_ORDER = ["fridge", "freezer", "pantry", "garage_freezer", "wine_fridge"];
const LOCATION_LABELS: Record<string, string> = {
  fridge: "Kyl",
  freezer: "Frys",
  pantry: "Skafferi",
  garage_freezer: "Garagefrys",
  wine_fridge: "Vinkyl",
};
const locLabel = (type: string) => LOCATION_LABELS[type] ?? type;
const orderIndex = (type: string) => {
  const i = LOCATION_ORDER.indexOf(type);
  return i === -1 ? LOCATION_ORDER.length : i;
};

export default function KitchenScreen() {
  const queryClient = useQueryClient();
  const params = useLocalSearchParams<{ loc?: string }>();
  const initialLoc = typeof params.loc === "string" ? params.loc : null;
  const [search, setSearch] = useState("");
  const [locFilter, setLocFilter] = useState<string | null>(initialLoc);
  const [selected, setSelected] = useState<Set<string>>(new Set());

  const query = useQuery({
    queryKey: ["inventory", "all"],
    queryFn: () => api<{ items: InventoryItem[] }>("/v1/inventory?limit=500"),
  });

  const bulkRemove = useMutation({
    mutationFn: (ids: string[]) =>
      api<{ deleted: number }>("/v1/inventory/bulk-delete", { method: "POST", body: { ids } }),
    onSuccess: () => setSelected(new Set()),
    onError: (err) =>
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error")),
    onSettled: () => {
      void queryClient.invalidateQueries({ queryKey: ["inventory"] });
      void queryClient.invalidateQueries({ queryKey: ["inventory-expiring"] });
      // Lagret styr receptförslagen – uppdatera "Vad ska vi äta?" direkt.
      void queryClient.invalidateQueries({ queryKey: ["what-to-eat"] });
    },
  });

  const all = query.data?.items ?? [];

  const locTypes = useMemo(() => {
    const set = new Set(all.map((i) => i.locationType));
    return [...set].sort((a, b) => orderIndex(a) - orderIndex(b) || a.localeCompare(b, "sv"));
  }, [all]);

  const q = search.trim().toLowerCase();
  const visible = useMemo(
    () =>
      all
        .filter((i) => (locFilter ? i.locationType === locFilter : true))
        .filter((i) => (q ? i.displayName.toLowerCase().includes(q) : true)),
    [all, locFilter, q],
  );

  const groups = useMemo(() => {
    const map = new Map<string, InventoryItem[]>();
    for (const it of visible) {
      const list = map.get(it.locationType) ?? [];
      list.push(it);
      map.set(it.locationType, list);
    }
    return [...map.entries()]
      .sort(([a], [b]) => orderIndex(a) - orderIndex(b) || a.localeCompare(b, "sv"))
      .map(([type, items]) => ({
        type,
        items: [...items].sort((x, y) => x.displayName.localeCompare(y.displayName, "sv")),
      }));
  }, [visible]);

  if (query.isLoading) return <LoadingView />;
  if (query.isError) return <ErrorView onRetry={() => void query.refetch()} />;

  const toggle = (id: string) =>
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });

  const confirmDelete = (ids: string[], label: string) => {
    if (ids.length === 0) return;
    Alert.alert(
      "Ta bort",
      `Är du säker på att du vill ta bort ${ids.length} ${ids.length === 1 ? "vara" : "varor"} ur ${label}?`,
      [
        { text: t("common.cancel"), style: "cancel" },
        { text: "Ta bort", style: "destructive", onPress: () => bulkRemove.mutate(ids) },
      ],
    );
  };

  const emptyLabel = locFilter ? locLabel(locFilter) : q ? "sökningen" : "hela lagret";

  return (
    <Screen>
      <Input value={search} onChangeText={setSearch} placeholder="Sök vara…" autoCorrect={false} />

      <Row>
        <Button
          label="Alla"
          variant={locFilter === null ? "primary" : "ghost"}
          onPress={() => setLocFilter(null)}
        />
        {locTypes.map((tp) => (
          <Button
            key={tp}
            label={locLabel(tp)}
            variant={locFilter === tp ? "primary" : "ghost"}
            onPress={() => setLocFilter(tp)}
          />
        ))}
      </Row>

      <Row style={{ justifyContent: "space-between" }}>
        <Small>
          {visible.length} varor{selected.size > 0 ? ` · ${selected.size} valda` : ""}
        </Small>
        <Row style={{ justifyContent: "flex-end" }}>
          {selected.size > 0 && (
            <Button
              label={`Ta bort valda (${selected.size})`}
              variant="danger"
              onPress={() => confirmDelete([...selected], "markeringen")}
            />
          )}
          {visible.length > 0 && (
            <Button
              label="Töm listan"
              variant="ghost"
              onPress={() => confirmDelete(visible.map((i) => i.id), emptyLabel)}
            />
          )}
        </Row>
      </Row>

      {visible.length === 0 && (
        <EmptyState text="Inga varor att visa. Skanna eller lägg till varor." />
      )}

      {groups.map((g) => (
        <View key={g.type} style={{ gap: spacing.xs, marginTop: spacing.sm }}>
          <Row style={{ justifyContent: "space-between" }}>
            <Heading>{locLabel(g.type)}</Heading>
            <Small>{g.items.length} st</Small>
          </Row>
          {g.items.map((item) => {
            const isSel = selected.has(item.id);
            return (
              <Card
                key={item.id}
                onPress={() => toggle(item.id)}
                style={isSel ? { borderColor: colors.primary, backgroundColor: colors.primarySoft } : undefined}
              >
                <Row style={{ justifyContent: "space-between" }}>
                  <Body>
                    {isSel ? "☑ " : "☐ "}
                    {item.displayName} · {formatQuantity(item.quantity, item.unit)}
                  </Body>
                  {item.expiry.pastBestBefore && <Small>⚠︎ bäst före</Small>}
                </Row>
              </Card>
            );
          })}
        </View>
      ))}
    </Screen>
  );
}
