"use client"

import { useEffect, useState } from "react"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { z } from "zod"
import { Loader2Icon } from "lucide-react"
import { toast } from "sonner"

import { Button } from "@/src/components/ui/button"
import { Input } from "@/src/components/ui/input"
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/src/components/ui/dialog"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/src/components/ui/form"
import { useUpdateMenuItemMutation } from "@/src/state/menu"
import { useUploadFileMutation } from "@/src/state/upload"
import type { MenuItem } from "@/src/state/menu"
import { extractErrorMessage } from "../utils"
import { CategoryCombobox } from "../category-combobox"
import { IngredientInput } from "../ingredient-input"
import { MenuImageUpload } from "../menu-image-upload"

const schema = z.object({
  categoryId: z.string().min(1, "Veuillez sélectionner une catégorie"),
  name: z.string().min(2, "Le nom doit contenir au moins 2 caractères"),
  price: z.coerce.number().positive("Le prix doit être positif"),
  description: z.string().optional(),
  ingredients: z.array(z.string()).optional(),
  preparationTime: z.coerce.number().int().positive().optional().or(z.literal("")),
})

type FormValues = z.infer<typeof schema>

type ImageField = "thumbnailImage" | "descriptiveImage"

type Props = {
  open: boolean
  onOpenChange: (open: boolean) => void
  item: MenuItem | null
}

export function EditItemDialog({ open, onOpenChange, item }: Props) {
  const [updateMenuItem, { isLoading }] = useUpdateMenuItemMutation()
  const [uploadFile] = useUploadFileMutation()

  const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(null)
  const [descriptiveUrl, setDescriptiveUrl] = useState<string | null>(null)
  const [uploadingField, setUploadingField] = useState<ImageField | null>(null)

  const form = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      categoryId: "",
      name: "",
      price: 0,
      description: "",
      ingredients: [],
      preparationTime: "",
    },
  })

  useEffect(() => {
    if (open && item) {
      form.reset({
        categoryId: item.category.id,
        name: item.name,
        price: item.price,
        description: item.description ?? "",
        ingredients: item.ingredients,
        preparationTime: item.preparationTime ?? "",
      })
      setThumbnailUrl(item.thumbnailImage)
      setDescriptiveUrl(item.descriptiveImage)
    }
  }, [open, item, form])

  const handleImageUpload = async (field: ImageField, file: File) => {
    setUploadingField(field)
    try {
      const formData = new FormData()
      formData.append("file", file)
      formData.append("fileType", "image")
      const res = await uploadFile(formData).unwrap()
      if (field === "thumbnailImage") setThumbnailUrl(res.data.url)
      else setDescriptiveUrl(res.data.url)
    } catch {
      toast.error("Erreur lors de l'envoi de l'image")
    } finally {
      setUploadingField(null)
    }
  }

  const handleImageDelete = (field: ImageField) => {
    if (field === "thumbnailImage") setThumbnailUrl(null)
    else setDescriptiveUrl(null)
    return Promise.resolve()
  }

  const handleSubmit = async (values: FormValues) => {
    if (!item) return
    try {
      await updateMenuItem({
        id: item.id,
        categoryId: values.categoryId,
        name: values.name,
        price: values.price,
        description: values.description || undefined,
        ingredients: values.ingredients,
        thumbnailImage: thumbnailUrl || undefined,
        descriptiveImage: descriptiveUrl || undefined,
        preparationTime: values.preparationTime ? Number(values.preparationTime) : undefined,
      }).unwrap()
      toast.success("Article mis à jour")
      onOpenChange(false)
    } catch (err) {
      toast.error(extractErrorMessage(err, "Une erreur est survenue"))
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>Modifier l&apos;article</DialogTitle>
        </DialogHeader>

        <Form {...form}>
          <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-5">
            <FormField
              control={form.control}
              name="categoryId"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Catégorie</FormLabel>
                  <FormControl>
                    <CategoryCombobox
                      value={field.value}
                      onChange={field.onChange}
                      disabled={isLoading}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="grid gap-4 sm:grid-cols-2">
              <FormField
                control={form.control}
                name="name"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Nom du plat</FormLabel>
                    <FormControl>
                      <Input placeholder="Ex: Burger Classic" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <FormField
                control={form.control}
                name="price"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Prix (FCFA)</FormLabel>
                    <FormControl>
                      <Input type="number" min={0} placeholder="0" {...field} />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <FormField
              control={form.control}
              name="description"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>
                    Description{" "}
                    <span className="text-muted-foreground font-normal">(optionnel)</span>
                  </FormLabel>
                  <FormControl>
                    <textarea
                      className="flex min-h-[80px] w-full rounded-lg border border-input bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 resize-none"
                      placeholder="Décrivez le plat…"
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="ingredients"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>
                    Ingrédients{" "}
                    <span className="text-muted-foreground font-normal">(optionnel)</span>
                  </FormLabel>
                  <FormControl>
                    <IngredientInput
                      value={field.value ?? []}
                      onChange={field.onChange}
                      disabled={isLoading}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="preparationTime"
              render={({ field }) => (
                <FormItem className="sm:max-w-[200px]">
                  <FormLabel>
                    Temps de préparation (min){" "}
                    <span className="text-muted-foreground font-normal">(optionnel)</span>
                  </FormLabel>
                  <FormControl>
                    <Input type="number" min={1} placeholder="15" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />

            <div className="grid gap-6 sm:grid-cols-2">
              <MenuImageUpload
                label="Image miniature"
                hint="Ratio 4:3 recommandé"
                currentUrl={thumbnailUrl}
                aspectRatio="4/3"
                isUploading={uploadingField === "thumbnailImage"}
                onUpload={(file) => handleImageUpload("thumbnailImage", file)}
                onDelete={() => handleImageDelete("thumbnailImage")}
              />

              <MenuImageUpload
                label="Image descriptive"
                hint="Ratio 4:3 recommandé"
                currentUrl={descriptiveUrl}
                aspectRatio="4/3"
                isUploading={uploadingField === "descriptiveImage"}
                onUpload={(file) => handleImageUpload("descriptiveImage", file)}
                onDelete={() => handleImageDelete("descriptiveImage")}
              />
            </div>

            <div className="flex justify-end gap-2 pt-2">
              <Button
                type="button"
                variant="outline"
                onClick={() => onOpenChange(false)}
                disabled={isLoading}
              >
                Annuler
              </Button>
              <Button type="submit" disabled={isLoading} className="min-w-32">
                {isLoading && <Loader2Icon className="animate-spin" />}
                Enregistrer
              </Button>
            </div>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  )
}
