"use client";

import { useRef, useState } from "react";
import { useTranslations } from "next-intl";
import { ScanBarcode, Camera, Loader2, X, ArrowLeft } from "lucide-react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { BarcodeScanner } from "@/components/pantry/barcode-scanner";

type Step = "choose" | "barcode-scan" | "barcode-confirm" | "photo-loading" | "photo-confirm";

type DraftItem = { rawName: string; quantity: string; unit: string };

function fileToBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result as string;
      const comma = result.indexOf(",");
      resolve(comma !== -1 ? result.slice(comma + 1) : result);
    };
    reader.onerror = () => reject(reader.error);
    reader.readAsDataURL(file);
  });
}

export function PantryScanDialog({ onAdded }: { onAdded: () => void }) {
  const t = useTranslations("pantry");
  const [open, setOpen] = useState(false);
  const [step, setStep] = useState<Step>("choose");
  const [barcodeDraft, setBarcodeDraft] = useState<DraftItem | null>(null);
  const [photoDrafts, setPhotoDrafts] = useState<DraftItem[]>([]);
  const [busy, setBusy] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  function reset() {
    setStep("choose");
    setBarcodeDraft(null);
    setPhotoDrafts([]);
  }

  function handleOpenChange(next: boolean) {
    setOpen(next);
    if (!next) reset();
  }

  async function handleBarcodeDetected(barcode: string) {
    setBusy(true);
    try {
      const res = await fetch("/api/v1/pantry/scan/barcode", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ barcode }),
      });
      if (!res.ok) {
        toast.error(t("scanLookupFailed"));
        setStep("choose");
        return;
      }
      const data = await res.json() as { found: boolean; rawName?: string; quantity?: string; unit?: string };
      if (!data.found || !data.rawName) {
        toast.error(t("scanNotFound"));
        setStep("choose");
        return;
      }
      setBarcodeDraft({ rawName: data.rawName, quantity: data.quantity ?? "", unit: data.unit ?? "" });
      setStep("barcode-confirm");
    } finally {
      setBusy(false);
    }
  }

  async function handlePhotoFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setStep("photo-loading");
    try {
      const imageBase64 = await fileToBase64(file);
      const mimeType = (["image/jpeg", "image/png", "image/webp"].includes(file.type) ? file.type : "image/jpeg") as
        | "image/jpeg"
        | "image/png"
        | "image/webp";

      const res = await fetch("/api/v1/pantry/scan/photo", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ imageBase64, mimeType }),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => ({})) as { error?: string };
        toast.error(data.error ?? t("scanPhotoFailed"));
        setStep("choose");
        return;
      }
      const data = await res.json() as { items: { rawName: string; estimatedQuantity?: string; unit?: string }[] };
      if (data.items.length === 0) {
        toast.error(t("scanNoItemsFound"));
        setStep("choose");
        return;
      }
      setPhotoDrafts(
        data.items.map((i) => ({ rawName: i.rawName, quantity: i.estimatedQuantity ?? "", unit: i.unit ?? "" }))
      );
      setStep("photo-confirm");
    } finally {
      if (fileRef.current) fileRef.current.value = "";
    }
  }

  async function confirmItems(items: DraftItem[]) {
    setBusy(true);
    try {
      const res = await fetch("/api/v1/pantry/bulk", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          items: items
            .filter((i) => i.rawName.trim())
            .map((i) => ({
              rawName: i.rawName.trim(),
              quantity: i.quantity.trim() || undefined,
              unit: i.unit.trim() || undefined,
            })),
        }),
      });
      if (!res.ok) {
        toast.error(t("addFailed"));
        return;
      }
      toast.success(t("scanAdded"));
      onAdded();
      handleOpenChange(false);
    } finally {
      setBusy(false);
    }
  }

  return (
    <>
      <Button variant="outline" size="sm" onClick={() => setOpen(true)}>
        <ScanBarcode className="h-4 w-4" /> {t("scan")}
      </Button>

      <Dialog open={open} onOpenChange={handleOpenChange}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>
              {step === "choose" && t("scanTitle")}
              {step === "barcode-scan" && t("scanBarcodeTitle")}
              {step === "barcode-confirm" && t("scanConfirmTitle")}
              {step === "photo-loading" && t("scanAnalyzingTitle")}
              {step === "photo-confirm" && t("scanConfirmTitle")}
            </DialogTitle>
            <DialogDescription>
              {step === "choose" && t("scanDescription")}
              {step === "barcode-scan" && t("scanBarcodeDescription")}
              {(step === "barcode-confirm" || step === "photo-confirm") && t("scanConfirmDescription")}
            </DialogDescription>
          </DialogHeader>

          {step === "choose" && (
            <div className="grid grid-cols-2 gap-3">
              <button
                type="button"
                onClick={() => setStep("barcode-scan")}
                className="flex flex-col items-center gap-2 rounded-lg border p-4 hover:bg-muted/50 transition-colors"
              >
                <ScanBarcode className="h-6 w-6" />
                <span className="text-sm font-medium">{t("scanBarcodeOption")}</span>
              </button>
              <button
                type="button"
                onClick={() => fileRef.current?.click()}
                className="flex flex-col items-center gap-2 rounded-lg border p-4 hover:bg-muted/50 transition-colors"
              >
                <Camera className="h-6 w-6" />
                <span className="text-sm font-medium">{t("scanPhotoOption")}</span>
              </button>
              <input
                ref={fileRef}
                type="file"
                accept="image/jpeg,image/png,image/webp"
                capture="environment"
                className="hidden"
                onChange={handlePhotoFile}
              />
            </div>
          )}

          {step === "barcode-scan" && (
            <div className="space-y-3">
              <BarcodeScanner
                onDetected={(barcode) => void handleBarcodeDetected(barcode)}
                onError={() => { toast.error(t("cameraError")); setStep("choose"); }}
              />
              <Button variant="ghost" size="sm" onClick={() => setStep("choose")} disabled={busy}>
                <ArrowLeft className="h-4 w-4" /> {t("scanBack")}
              </Button>
            </div>
          )}

          {step === "barcode-confirm" && barcodeDraft && (
            <div className="space-y-3">
              <div className="flex gap-2">
                <Input
                  value={barcodeDraft.rawName}
                  onChange={(e) => setBarcodeDraft({ ...barcodeDraft, rawName: e.target.value })}
                  placeholder={t("itemNamePlaceholder")}
                  className="flex-1"
                />
                <Input
                  value={barcodeDraft.quantity}
                  onChange={(e) => setBarcodeDraft({ ...barcodeDraft, quantity: e.target.value })}
                  placeholder={t("qtyPlaceholder")}
                  className="w-20"
                />
                <Input
                  value={barcodeDraft.unit}
                  onChange={(e) => setBarcodeDraft({ ...barcodeDraft, unit: e.target.value })}
                  placeholder={t("unitPlaceholder")}
                  className="w-20"
                />
              </div>
            </div>
          )}

          {step === "photo-loading" && (
            <div className="flex flex-col items-center justify-center gap-3 py-8">
              <Loader2 className="h-6 w-6 animate-spin" />
              <p className="text-sm text-muted-foreground">{t("scanAnalyzingDescription")}</p>
            </div>
          )}

          {step === "photo-confirm" && (
            <div className="space-y-2 max-h-80 overflow-y-auto">
              {photoDrafts.map((draft, i) => (
                <div key={i} className="flex items-center gap-2">
                  <Input
                    value={draft.rawName}
                    onChange={(e) =>
                      setPhotoDrafts((prev) => prev.map((d, idx) => (idx === i ? { ...d, rawName: e.target.value } : d)))
                    }
                    className="flex-1"
                  />
                  <Input
                    value={draft.quantity}
                    onChange={(e) =>
                      setPhotoDrafts((prev) => prev.map((d, idx) => (idx === i ? { ...d, quantity: e.target.value } : d)))
                    }
                    placeholder={t("qtyPlaceholder")}
                    className="w-16"
                  />
                  <Input
                    value={draft.unit}
                    onChange={(e) =>
                      setPhotoDrafts((prev) => prev.map((d, idx) => (idx === i ? { ...d, unit: e.target.value } : d)))
                    }
                    placeholder={t("unitPlaceholder")}
                    className="w-16"
                  />
                  <button
                    type="button"
                    onClick={() => setPhotoDrafts((prev) => prev.filter((_, idx) => idx !== i))}
                    className="text-muted-foreground hover:text-destructive transition-colors"
                  >
                    <X className="h-4 w-4" />
                  </button>
                </div>
              ))}
            </div>
          )}

          {(step === "barcode-confirm" || step === "photo-confirm") && (
            <DialogFooter>
              <Button variant="outline" onClick={reset} disabled={busy}>
                {t("scanBack")}
              </Button>
              <Button
                onClick={() =>
                  void confirmItems(step === "barcode-confirm" && barcodeDraft ? [barcodeDraft] : photoDrafts)
                }
                disabled={busy}
              >
                {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : t("scanAddToPantry")}
              </Button>
            </DialogFooter>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
