"use client"

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

import { Button } from "@/src/components/ui/button"
import { Input } from "@/src/components/ui/input"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/src/components/ui/form"
import {
  useFetchMenuQuery,
  useUpdateMenuItemMutation,
  useToggleItemAvailabilityMutation,
} from "@/src/state/menu"
import { useUploadFileMutation } from "@/src/state/upload"
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 = {
  id: string
}

export default function EditItemPage({ id }: Props) {
  const router = useRouter()
  const { data, isLoading: isFetching } = useFetchMenuQuery({})
  const [updateMenuItem, { isLoading: isSaving }] = useUpdateMenuItemMutation()
  const [toggleAvailability, { isLoading: isToggling }] = useToggleItemAvailabilityMutation()
  const [uploadFile] = useUploadFileMutation()

  const item = data?.data?.items.find((i) => i.id === id) ?? null

  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 (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)
    }
  }, [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 handleToggleAvailability = async () => {
    if (!item) return
    try {
      await toggleAvailability(item.id).unwrap()
      toast.success(
        item.isAvailable ? "Article marqué indisponible" : "Article marqué disponible"
      )
    } catch (err) {
      toast.error(extractErrorMessage(err, "Erreur lors de la mise à jour"))
    }
  }

  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")
      router.push("/menu/items")
    } catch (err) {
      toast.error(extractErrorMessage(err, "Une erreur est survenue"))
    }
  }

  if (isFetching) {
    return (
      <div className="min-h-[80svh] flex items-center justify-center">
        <Loader2Icon className="animate-spin text-muted-foreground" />
      </div>
    )
  }

  if (!item) {
    return (
      <div className="min-h-[80svh] flex flex-col items-center justify-center gap-3">
        <p className="text-sm font-medium">Article introuvable</p>
        <Button variant="outline" onClick={() => router.push("/menu/items")}>
          Retour au menu
        </Button>
      </div>
    )
  }

  return (
    <div className="max-w-5xl mx-auto px-4 py-8 space-y-8">
      <div className="flex items-center gap-3">
        <Button
          type="button"
          variant="ghost"
          size="icon"
          onClick={() => router.push("/menu/items")}
        >
          <ArrowLeftIcon className="size-4" />
        </Button>
        <div>
          <h1 className="text-xl font-semibold">Modifier l&apos;article</h1>
          <p className="text-sm text-muted-foreground mt-0.5">{item.name}</p>
        </div>
      </div>

      <section className="rounded-xl border bg-white p-5 space-y-4">
        <div>
          <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
            Disponibilité
          </h2>
          <p className="text-xs text-muted-foreground mt-0.5">
            Désactivez cet article si un ingrédient vient à manquer
          </p>
        </div>

        <div className="flex items-center justify-between">
          <div className="space-y-0.5">
            <p className="text-sm font-medium">
              {item.isAvailable ? "Disponible à la commande" : "Indisponible à la commande"}
            </p>
            <p className="text-xs text-muted-foreground">
              {item.isAvailable
                ? "Cet article est visible et commandable par les clients"
                : "Cet article est masqué et ne peut pas être commandé"}
            </p>
          </div>

          <button
            type="button"
            disabled={isToggling}
            onClick={handleToggleAvailability}
            className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 ${
              item.isAvailable ? "bg-primary" : "bg-input"
            }`}
          >
            {isToggling ? (
              <Loader2Icon className="absolute inset-0 m-auto size-3.5 animate-spin text-white" />
            ) : (
              <span
                className={`pointer-events-none block size-5 rounded-full bg-white shadow-lg ring-0 transition-transform ${
                  item.isAvailable ? "translate-x-5" : "translate-x-0"
                }`}
              />
            )}
          </button>
        </div>
      </section>

      <Form {...form}>
        <form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
          <section className="space-y-4 rounded-xl border bg-white p-5">
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Informations générales
            </h2>

            <FormField
              control={form.control}
              name="categoryId"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Catégorie</FormLabel>
                  <FormControl>
                    <CategoryCombobox
                      value={field.value}
                      onChange={field.onChange}
                      disabled={isSaving}
                    />
                  </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>
              )}
            />
          </section>

          <section className="space-y-4 rounded-xl border bg-white p-5">
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Ingrédients &amp; préparation
            </h2>

            <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={isSaving}
                    />
                  </FormControl>
                  <p className="text-xs text-muted-foreground">
                    Appuyez sur Entrée ou virgule pour ajouter un ingrédient
                  </p>
                  <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>
              )}
            />
          </section>

          <section className="space-y-4 rounded-xl border bg-white p-5">
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Images
            </h2>

            <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>
          </section>

          <div className="flex justify-end gap-2">
            <Button
              type="button"
              variant="outline"
              onClick={() => router.push("/menu/items")}
              disabled={isSaving}
            >
              Annuler
            </Button>
            <Button type="submit" disabled={isSaving} className="min-w-32">
              {isSaving && <Loader2Icon className="animate-spin" />}
              Enregistrer
            </Button>
          </div>
        </form>
      </Form>
    </div>
  )
}
