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

/**
 * Granska AI-resultat (spec §10, §61.4–5): användaren godkänner, ändrar,
 * tar bort och lägger till INNAN något skrivs till Food Twin.
 * Osäkra rader flaggas tydligt. Ändringar blir ai_corrections → AAMOS-träning.
 */

interface DetectedItem {
  tempId?: string;
  detectedName: string;
  canonicalIngredientId: string | null;
  brand: string | null;
  estimatedQuantity: number | null;
  unit: string | null;
  bestBeforeDate: string | null;
  confidence: number;
  requiresConfirmation: boolean;
}
interface ScanJob {
  id: string;
  status: string;
  scanType: string;
  error: string | null;
  result: { items?: DetectedItem[] } | null;
}

interface EditableItem {
  tempId: string;
  original: DetectedItem | null;
  name: string;
  quantity: string;
  unit: string;
  canonicalIngredientId: string | null;
  date: string;
  /**
   * Datumtyp (spec §13): "Bäst före" är en KVALITETSgräns (varan kan vara god
   * längre – lukta och smaka), "Sista förbrukningsdag" en SÄKERHETSgräns.
   * Användaren väljer typ så att appen aldrig dömer mat i onödan – och aldrig
   * mjukar upp en riktig säkerhetsgräns.
   */
  dateIsUseBy: boolean;
  confidence: number;
  rejected: boolean;
}

export default function ScanReviewScreen() {
  const { jobId } = useLocalSearchParams<{ jobId: string }>();
  const queryClient = useQueryClient();
  const [items, setItems] = useState<EditableItem[] | null>(null);
  const [busy, setBusy] = useState(false);

  const query = useQuery({
    queryKey: ["scan", jobId],
    queryFn: () => api<ScanJob>(`/v1/scans/${jobId}`),
    refetchInterval: (q) => {
      const status = q.state.data?.status;
      return status === "queued" || status === "running" ? 1500 : false;
    },
  });

  const job = query.data;

  // Initiera redigerbara rader när resultatet landar
  useMemo(() => {
    if (job?.status === "awaiting_confirmation" && job.result?.items && items == null) {
      setItems(
        job.result.items.map((item, index) => ({
          tempId: item.tempId ?? `item-${index}`,
          original: item,
          name: item.detectedName,
          quantity: item.estimatedQuantity != null ? String(item.estimatedQuantity) : "1",
          unit: unitLabel(item.unit ?? "COUNT"),
          canonicalIngredientId: item.canonicalIngredientId,
          date: item.bestBeforeDate ?? "",
          dateIsUseBy: false,
          confidence: item.confidence,
          rejected: false,
        })),
      );
    }
  }, [job, items]);

  const update = (tempId: string, patch: Partial<EditableItem>) =>
    setItems((prev) => prev?.map((i) => (i.tempId === tempId ? { ...i, ...patch } : i)) ?? null);

  const addManual = () =>
    setItems((prev) => [
      ...(prev ?? []),
      {
        tempId: `manual-${Date.now()}`,
        original: null,
        name: "",
        quantity: "1",
        unit: unitLabel("COUNT"),
        canonicalIngredientId: null,
        date: "",
        dateIsUseBy: false,
        confidence: 1,
        rejected: false,
      },
    ]);

  const confirm = async () => {
    if (!items) return;
    setBusy(true);
    try {
      const payload = items
        .filter((i) => i.rejected || i.name.trim().length > 0)
        .map((i) => {
          const edited =
            i.original == null ||
            i.name !== i.original.detectedName ||
            Number(i.quantity) !== i.original.estimatedQuantity ||
            i.unit !== (i.original.unit ?? "st");
          return {
            tempId: i.tempId,
            action: i.rejected ? "reject" : i.original == null ? "add" : edited ? "edit" : "accept",
            displayName: i.name.trim() || i.original?.detectedName || t("scan.review.unknownItem"),
            canonicalIngredientId: i.canonicalIngredientId ?? undefined,
            quantity: Math.max(0.01, Number(i.quantity) || 1),
            unit: parseUnitInput(i.unit) ?? "COUNT",
            // Rätt kolumn per datumtyp – motorn behandlar dem helt olika (spec §13).
            bestBeforeDate: !i.dateIsUseBy && i.date ? i.date : undefined,
            useByDate: i.dateIsUseBy && i.date ? i.date : undefined,
          };
        });
      await api(`/v1/scans/${jobId}/confirm`, { method: "POST", body: { items: payload } });
      await queryClient.invalidateQueries({ queryKey: ["inventory"] });
      await queryClient.invalidateQueries({ queryKey: ["what-to-eat"] });
      router.back();
    } catch (err) {
      Alert.alert(t("common.oops"), err instanceof Error ? err.message : t("common.error"));
    } finally {
      setBusy(false);
    }
  };

  if (query.isLoading || job?.status === "queued" || job?.status === "running") {
    return (
      <Screen scroll={false}>
        <LoadingView />
        <Body muted>{t("scan.analyzing")}</Body>
      </Screen>
    );
  }
  if (query.isError || !job) return <ErrorView onRetry={() => void query.refetch()} />;
  if (job.status === "failed") {
    return (
      <Screen>
        <ErrorView message={job.error ?? t("scan.failed")} onRetry={() => router.back()} />
      </Screen>
    );
  }

  return (
    <Screen>
      <Heading>{t("scan.review.title")}</Heading>
      <Small>{t("scan.review.subtitle")}</Small>
      <Spacer size={spacing.sm} />

      {(items ?? []).map((item) => (
        <Card key={item.tempId} style={item.rejected ? { opacity: 0.4 } : undefined}>
          <Row style={{ justifyContent: "space-between" }}>
            {item.confidence < 0.7 && !item.rejected ? (
              <Tag label={`⚠️ ${t("scan.review.uncertain")}`} tone="warning" />
            ) : (
              <View />
            )}
            <Button
              label={item.rejected ? t("common.undo") : t("common.remove")}
              variant="ghost"
              onPress={() => update(item.tempId, { rejected: !item.rejected })}
            />
          </Row>
          {!item.rejected && (
            <>
              <Input
                value={item.name}
                onChangeText={(v) => update(item.tempId, { name: v })}
                placeholder={t("scan.review.itemPlaceholder")}
              />
              <Row>
                <View style={{ flex: 1 }}>
                  <Input
                    value={item.quantity}
                    keyboardType="numeric"
                    onChangeText={(v) => update(item.tempId, { quantity: v })}
                    placeholder={t("scan.review.quantityPlaceholder")}
                  />
                </View>
                <View style={{ flex: 1 }}>
                  <Input
                    value={item.unit}
                    onChangeText={(v) => update(item.tempId, { unit: v })}
                    placeholder={t("scan.review.unitPlaceholder")}
                  />
                </View>
              </Row>
              {/* Datumtyp (spec §13): bäst före = kvalitet, sista förbrukningsdag = säkerhet. */}
              <Row>
                <Button
                  label={t("scan.review.dateKindBestBefore")}
                  variant={item.dateIsUseBy ? "ghost" : "secondary"}
                  onPress={() => update(item.tempId, { dateIsUseBy: false })}
                />
                <Button
                  label={t("scan.review.dateKindUseBy")}
                  variant={item.dateIsUseBy ? "secondary" : "ghost"}
                  onPress={() => update(item.tempId, { dateIsUseBy: true })}
                />
              </Row>
              <Input
                value={item.date}
                onChangeText={(v) => update(item.tempId, { date: v })}
                placeholder={t("scan.review.datePlaceholder")}
              />
              {item.date.length > 0 && (
                <Small>
                  {item.dateIsUseBy ? t("scan.review.useByNote") : t("scan.review.bestBeforeNote")}
                </Small>
              )}
            </>
          )}
        </Card>
      ))}

      <Button label={t("scan.review.addItem")} variant="ghost" onPress={addManual} />
      <Spacer size={spacing.sm} />
      <Button label={t("scan.review.approveAll")} onPress={() => void confirm()} loading={busy} />
    </Screen>
  );
}
