"use client";

import Image from "next/image";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import {
  ADMIN_API,
  CATEGORY_LABELS,
  WAFFLE_CATEGORIES,
} from "@/lib/constants";
import { DEFAULT_CUSTOM_WAFFLE } from "@/lib/custom-waffle";
import { isUploadAssetPath } from "@/lib/image-url";
import type { Ingredient, Waffle } from "@/generated/prisma/client";

const categories = Object.values(WAFFLE_CATEGORIES);

type AdminWaffle = Waffle & {
  ingredientItems: Pick<Ingredient, "id" | "name">[];
};

export function AdminDashboard() {
  const router = useRouter();
  const [waffles, setWaffles] = useState<AdminWaffle[]>([]);
  const [catalog, setCatalog] = useState<Ingredient[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [customWaffleForm, setCustomWaffleForm] = useState({
    title: DEFAULT_CUSTOM_WAFFLE.title,
    description: DEFAULT_CUSTOM_WAFFLE.description,
    basePrice: String(DEFAULT_CUSTOM_WAFFLE.basePrice),
    visible: DEFAULT_CUSTOM_WAFFLE.visible,
  });
  const [customWaffleLoaded, setCustomWaffleLoaded] = useState(false);
  const [savingCustomWaffle, setSavingCustomWaffle] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState<{
    name: string;
    ingredients: string;
    price: string;
    category: string;
    isNew: boolean;
    imageUrl: string;
    ingredientIds: string[];
  }>({
    name: "",
    ingredients: "",
    price: "",
    category: WAFFLE_CATEGORIES.SUCREE,
    isNew: false,
    imageUrl: "",
    ingredientIds: [],
  });

  const load = useCallback(async () => {
    const [wafflesRes, ingredientsRes, customWaffleRes] = await Promise.all([
      fetch(`${ADMIN_API}/waffles`, { credentials: "include" }),
      fetch(`${ADMIN_API}/ingredients`, { credentials: "include" }),
      fetch(`${ADMIN_API}/custom-waffle`, { credentials: "include" }),
    ]);
    if (
      wafflesRes.status === 401 ||
      ingredientsRes.status === 401 ||
      customWaffleRes.status === 401
    ) {
      router.replace("/admin/login");
      return;
    }
    const wafflesData = await wafflesRes.json();
    const ingredientsData = await ingredientsRes.json();
    const customWaffleData = await customWaffleRes.json().catch(() => null);
    setWaffles(Array.isArray(wafflesData) ? wafflesData : []);
    setCatalog(Array.isArray(ingredientsData) ? ingredientsData : []);
    if (customWaffleData && typeof customWaffleData === "object") {
      setCustomWaffleForm({
        title: String(customWaffleData.title ?? DEFAULT_CUSTOM_WAFFLE.title),
        description: String(
          customWaffleData.description ?? DEFAULT_CUSTOM_WAFFLE.description
        ),
        basePrice: String(
          customWaffleData.basePrice ?? DEFAULT_CUSTOM_WAFFLE.basePrice
        ),
        visible: customWaffleData.visible !== false,
      });
    }
    setCustomWaffleLoaded(true);
    setLoading(false);
  }, [router]);

  useEffect(() => {
    load();
  }, [load]);

  function resetForm() {
    setEditingId(null);
    setForm({
      name: "",
      ingredients: "",
      price: "",
      category: WAFFLE_CATEGORIES.SUCREE,
      isNew: false,
      imageUrl: "",
      ingredientIds: [],
    });
  }

  function toggleIngredient(id: string) {
    setForm((f) => ({
      ...f,
      ingredientIds: f.ingredientIds.includes(id)
        ? f.ingredientIds.filter((x) => x !== id)
        : [...f.ingredientIds, id],
    }));
  }

  function startEdit(w: AdminWaffle) {
    setEditingId(w.id);
    setForm({
      name: w.name,
      ingredients: w.ingredients,
      price: String(w.price),
      category: w.category,
      isNew: w.isNew,
      imageUrl: w.imageUrl ?? "",
      ingredientIds: w.ingredientItems.map((i) => i.id),
    });
  }

  async function uploadFile(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append("file", file);
      const res = await fetch(`${ADMIN_API}/upload`, {
        method: "POST",
        body: fd,
        credentials: "include",
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        alert(typeof data.error === "string" ? data.error : "Échec de l’envoi");
        return;
      }
      if (data.url) setForm((f) => ({ ...f, imageUrl: data.url }));
    } finally {
      setUploading(false);
      e.target.value = "";
    }
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    const price = parseFloat(form.price.replace(",", "."));
    if (Number.isNaN(price) || price < 0) return;
    setSaving(true);
    try {
      const body = {
        name: form.name.trim(),
        ingredients: form.ingredients.trim(),
        price,
        category: form.category,
        isNew: form.isNew,
        imageUrl: form.imageUrl.trim() || null,
        ingredientIds: form.ingredientIds,
      };
      if (editingId) {
        const res = await fetch(`${ADMIN_API}/waffles/${editingId}`, {
          method: "PUT",
          headers: { "Content-Type": "application/json" },
          credentials: "include",
          body: JSON.stringify(body),
        });
        if (res.status === 401) {
          router.replace("/admin/login");
          return;
        }
        if (!res.ok) return;
      } else {
        const res = await fetch(`${ADMIN_API}/waffles`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          credentials: "include",
          body: JSON.stringify(body),
        });
        if (res.status === 401) {
          router.replace("/admin/login");
          return;
        }
        if (!res.ok) return;
      }
      resetForm();
      await load();
    } finally {
      setSaving(false);
    }
  }

  async function saveCustomWaffle(e: React.FormEvent) {
    e.preventDefault();
    const basePrice = parseFloat(customWaffleForm.basePrice.replace(",", "."));
    if (Number.isNaN(basePrice) || basePrice < 0) return;
    setSavingCustomWaffle(true);
    try {
      const res = await fetch(`${ADMIN_API}/custom-waffle`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({
          title: customWaffleForm.title.trim(),
          description: customWaffleForm.description.trim(),
          basePrice,
          visible: customWaffleForm.visible,
        }),
      });
      if (res.status === 401) {
        router.replace("/admin/login");
        return;
      }
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        alert(typeof data.error === "string" ? data.error : "Échec de l’enregistrement");
      }
    } finally {
      setSavingCustomWaffle(false);
    }
  }

  async function remove(id: string) {
    if (!confirm("Supprimer cette gaufre ?")) return;
    const res = await fetch(`${ADMIN_API}/waffles/${id}`, {
      method: "DELETE",
      credentials: "include",
    });
    if (res.status === 401) {
      router.replace("/admin/login");
      return;
    }
    if (editingId === id) resetForm();
    await load();
  }

  async function logout() {
    const res = await fetch(`${ADMIN_API}/auth/logout`, {
      method: "POST",
      credentials: "include",
    });
    if (res.ok) {
      window.location.href = "/admin/login";
      return;
    }
    router.replace("/admin/login");
    router.refresh();
  }

  return (
    <div className="px-4 py-10 sm:px-6">
      <div className="mx-auto max-w-4xl">
        <div className="mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className="text-2xl font-bold text-chocolat">Menu à l’affiche</h1>
            <p className="text-sm text-muted">
              Ajoutez une photo (fichier ou lien), modifiez ou retirez les gaufres
              visibles sur le site.
            </p>
          </div>
          <div className="flex flex-wrap gap-2">
            <a
              href="/"
              target="_blank"
              rel="noopener noreferrer"
              className="rounded-full border border-chocolat/20 px-4 py-2 text-sm font-medium text-chocolat hover:bg-white"
            >
              Voir le site
            </a>
            <button
              type="button"
              onClick={() => logout()}
              className="rounded-full bg-chocolat px-4 py-2 text-sm font-medium text-cream hover:opacity-90"
            >
              Déconnexion
            </button>
          </div>
        </div>

        <form
          onSubmit={onSubmit}
          className="mb-10 rounded-[2rem] border border-chocolat/10 bg-white p-6 shadow-[0_12px_40px_-12px_rgba(61,43,31,0.12)]"
        >
          <h2 className="text-lg font-semibold text-chocolat">
            {editingId ? "Modifier la gaufre" : "Nouvelle gaufre"}
          </h2>
          <div className="mt-4 grid gap-4 sm:grid-cols-2">
            <label className="flex flex-col gap-1 text-sm font-medium text-chocolat sm:col-span-2">
              Nom
              <input
                value={form.name}
                onChange={(e) =>
                  setForm((f) => ({ ...f, name: e.target.value }))
                }
                required
                className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
              />
            </label>
            <label className="flex flex-col gap-1 text-sm font-medium text-chocolat sm:col-span-2">
              Description
              <textarea
                value={form.ingredients}
                onChange={(e) =>
                  setForm((f) => ({ ...f, ingredients: e.target.value }))
                }
                required
                rows={3}
                className="resize-y rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
              />
            </label>
            <div className="flex flex-col gap-2 sm:col-span-2">
              <span className="text-sm font-medium text-chocolat">
                Ingrédients de la gaufre{" "}
                <span className="font-normal text-muted">(facultatif)</span>
              </span>
              {catalog.length === 0 ? (
                <p className="text-sm text-muted">
                  Aucun ingrédient en base.{" "}
                  <a
                    href="/admin/ingredients"
                    className="font-medium text-chocolat underline"
                  >
                    Créer des ingrédients
                  </a>
                </p>
              ) : (
                <ul className="max-h-48 space-y-2 overflow-y-auto rounded-2xl border border-chocolat/15 bg-cream/30 p-3">
                  {catalog.map((ing) => {
                    const checked = form.ingredientIds.includes(ing.id);
                    return (
                      <li key={ing.id}>
                        <label className="flex cursor-pointer items-center gap-3 rounded-xl px-2 py-1.5 hover:bg-white/80">
                          <input
                            type="checkbox"
                            checked={checked}
                            onChange={() => toggleIngredient(ing.id)}
                            className="size-4 rounded border-chocolat/30 text-gaufre focus:ring-gaufre"
                          />
                          {ing.imageUrl ? (
                            <span className="relative h-8 w-10 shrink-0 overflow-hidden rounded-lg border border-chocolat/10 bg-chocolat/5">
                              {ing.imageUrl.startsWith("http") ? (
                                // eslint-disable-next-line @next/next/no-img-element
                                <img
                                  src={ing.imageUrl}
                                  alt=""
                                  className="h-full w-full object-cover"
                                />
                              ) : (
                                <Image
                                  src={ing.imageUrl}
                                  alt=""
                                  fill
                                  unoptimized={isUploadAssetPath(ing.imageUrl)}
                                  className="object-cover"
                                  sizes="40px"
                                />
                              )}
                            </span>
                          ) : null}
                          <span className="min-w-0 flex-1 text-sm text-chocolat">
                            {ing.name}
                          </span>
                          <span className="shrink-0 text-xs font-semibold text-gaufre">
                            {ing.price.toFixed(2).replace(".", ",")} €
                          </span>
                        </label>
                      </li>
                    );
                  })}
                </ul>
              )}
            </div>
            <label className="flex flex-col gap-1 text-sm font-medium text-chocolat">
              Prix (€)
              <input
                type="text"
                inputMode="decimal"
                value={form.price}
                onChange={(e) =>
                  setForm((f) => ({ ...f, price: e.target.value }))
                }
                required
                placeholder="6,50"
                className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
              />
            </label>
            <label className="flex flex-col gap-1 text-sm font-medium text-chocolat">
              Catégorie
              <select
                value={form.category}
                onChange={(e) =>
                  setForm((f) => ({ ...f, category: e.target.value }))
                }
                className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
              >
                {categories.map((c) => (
                  <option key={c} value={c}>
                    {CATEGORY_LABELS[c] ?? c}
                  </option>
                ))}
              </select>
            </label>
            <div className="flex flex-col gap-2 sm:col-span-2">
              <span className="text-sm font-medium text-chocolat">Photo</span>
              <div className="flex flex-wrap items-end gap-3">
                <label className="inline-flex cursor-pointer items-center rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 text-sm font-medium text-chocolat hover:bg-cream">
                  <input
                    type="file"
                    accept="image/jpeg,image/png,image/webp,image/gif"
                    className="sr-only"
                    onChange={uploadFile}
                    disabled={uploading}
                  />
                  {uploading ? "Envoi…" : "Choisir un fichier"}
                </label>
                <span className="text-xs text-muted">ou colle une URL ci-dessous</span>
              </div>
              <input
                type="text"
                value={form.imageUrl}
                onChange={(e) =>
                  setForm((f) => ({ ...f, imageUrl: e.target.value }))
                }
                placeholder="https://… ou /uploads/… ou /gallery/…"
                autoComplete="off"
                className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 text-sm outline-none ring-gaufre/40 focus:ring-2"
              />
              <p className="text-xs text-muted">
                Chemin local (ex. <code className="rounded bg-chocolat/5 px-1">/gallery/nom.png</code>) ou lien https.
              </p>
              {form.imageUrl.trim() ? (
                <div className="mt-2 flex items-start gap-3">
                  <div className="relative h-24 w-36 shrink-0 overflow-hidden rounded-xl border border-chocolat/10 bg-chocolat/5">
                    {form.imageUrl.startsWith("http") ? (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img
                        src={form.imageUrl}
                        alt="Aperçu"
                        className="h-full w-full object-cover"
                      />
                    ) : (
                      <Image
                        src={form.imageUrl}
                        alt="Aperçu"
                        fill
                        unoptimized={isUploadAssetPath(form.imageUrl)}
                        className="object-cover"
                        sizes="144px"
                      />
                    )}
                  </div>
                  <button
                    type="button"
                    onClick={() => setForm((f) => ({ ...f, imageUrl: "" }))}
                    className="text-sm text-red-700 underline"
                  >
                    Retirer la photo
                  </button>
                </div>
              ) : null}
            </div>
            <label className="flex items-center gap-2 text-sm font-medium text-chocolat sm:col-span-2">
              <input
                type="checkbox"
                checked={form.isNew}
                onChange={(e) =>
                  setForm((f) => ({ ...f, isNew: e.target.checked }))
                }
                className="size-4 rounded border-chocolat/30 text-gaufre focus:ring-gaufre"
              />
              Badge « Nouveauté »
            </label>
          </div>
          <div className="mt-6 flex flex-wrap gap-3">
            <button
              type="submit"
              disabled={saving || uploading}
              className="rounded-full bg-gaufre px-6 py-2.5 text-sm font-semibold text-chocolat shadow-md disabled:opacity-60"
            >
              {saving
                ? "Enregistrement…"
                : editingId
                  ? "Mettre à jour"
                  : "Ajouter"}
            </button>
            {editingId && (
              <button
                type="button"
                onClick={resetForm}
                className="rounded-full border border-chocolat/20 px-6 py-2.5 text-sm font-medium text-chocolat"
              >
                Annuler
              </button>
            )}
          </div>
        </form>

        {loading ? (
          <p className="text-muted">Chargement…</p>
        ) : (
          <>
          {customWaffleLoaded ? (
            <form
              onSubmit={saveCustomWaffle}
              className="mb-8 rounded-[2rem] border border-gaufre/30 bg-white p-6 shadow-[0_12px_40px_-12px_rgba(61,43,31,0.12)] ring-1 ring-gaufre/20"
            >
              <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
                <div>
                  <h2 className="text-lg font-semibold text-chocolat">
                    Gaufre sur mesure
                  </h2>
                  <p className="mt-1 text-sm text-muted">
                    Carte affichée en tête de la section « Gaufre du moment » sur
                    le site public.
                  </p>
                </div>
                <div
                  className="flex items-center gap-3"
                  role="group"
                  aria-label="Visibilité sur le site"
                >
                  <span
                    className={`text-xs font-semibold uppercase tracking-wide ${
                      customWaffleForm.visible ? "text-muted" : "text-chocolat"
                    }`}
                  >
                    OFF
                  </span>
                  <button
                    type="button"
                    role="switch"
                    aria-checked={customWaffleForm.visible}
                    onClick={() =>
                      setCustomWaffleForm((f) => ({
                        ...f,
                        visible: !f.visible,
                      }))
                    }
                    className={`relative h-8 w-14 shrink-0 rounded-full transition-colors ${
                      customWaffleForm.visible ? "bg-gaufre" : "bg-chocolat/25"
                    }`}
                  >
                    <span
                      className={`absolute top-1 left-1 h-6 w-6 rounded-full bg-white shadow transition-transform ${
                        customWaffleForm.visible
                          ? "translate-x-6"
                          : "translate-x-0"
                      }`}
                    />
                  </button>
                  <span
                    className={`text-xs font-semibold uppercase tracking-wide ${
                      customWaffleForm.visible ? "text-chocolat" : "text-muted"
                    }`}
                  >
                    ON
                  </span>
                </div>
              </div>
              <p className="mt-2 text-xs text-muted">
                {customWaffleForm.visible
                  ? "ON : la carte est visible sur le menu public."
                  : "OFF : la carte est masquée sur le site."}
              </p>
              <div className="mt-4 grid gap-4 sm:grid-cols-2">
                <label className="flex flex-col gap-1 text-sm font-medium text-chocolat sm:col-span-2">
                  Titre
                  <input
                    value={customWaffleForm.title}
                    onChange={(e) =>
                      setCustomWaffleForm((f) => ({
                        ...f,
                        title: e.target.value,
                      }))
                    }
                    required
                    className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                  />
                </label>
                <label className="flex flex-col gap-1 text-sm font-medium text-chocolat sm:col-span-2">
                  Description
                  <textarea
                    value={customWaffleForm.description}
                    onChange={(e) =>
                      setCustomWaffleForm((f) => ({
                        ...f,
                        description: e.target.value,
                      }))
                    }
                    required
                    rows={3}
                    className="resize-y rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                  />
                </label>
                <label className="flex flex-col gap-1 text-sm font-medium text-chocolat">
                  Prix minimum (€)
                  <input
                    type="text"
                    inputMode="decimal"
                    value={customWaffleForm.basePrice}
                    onChange={(e) =>
                      setCustomWaffleForm((f) => ({
                        ...f,
                        basePrice: e.target.value,
                      }))
                    }
                    required
                    placeholder="3,00"
                    className="rounded-2xl border border-chocolat/15 bg-cream/50 px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                  />
                </label>
              </div>
              <div className="mt-6">
                <button
                  type="submit"
                  disabled={savingCustomWaffle}
                  className="rounded-full bg-gaufre px-6 py-2.5 text-sm font-semibold text-chocolat shadow-md disabled:opacity-60"
                >
                  {savingCustomWaffle
                    ? "Enregistrement…"
                    : "Enregistrer la gaufre sur mesure"}
                </button>
              </div>
            </form>
          ) : null}
          <ul className="space-y-3">
            {waffles.map((w) => (
              <li
                key={w.id}
                className="flex flex-col gap-3 rounded-2xl border border-chocolat/10 bg-white p-4 shadow-sm sm:flex-row sm:items-start sm:justify-between"
              >
                <div className="flex min-w-0 gap-3">
                  {w.imageUrl ? (
                    <div className="relative h-16 w-24 shrink-0 overflow-hidden rounded-xl border border-chocolat/10 bg-chocolat/5">
                      {w.imageUrl.startsWith("http") ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img
                          src={w.imageUrl}
                          alt=""
                          className="h-full w-full object-cover"
                        />
                      ) : (
                        <Image
                          src={w.imageUrl}
                          alt=""
                          fill
                          unoptimized={isUploadAssetPath(w.imageUrl)}
                          className="object-cover"
                          sizes="96px"
                        />
                      )}
                    </div>
                  ) : null}
                  <div className="min-w-0">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="font-semibold text-chocolat">{w.name}</span>
                    {w.isNew && (
                      <span className="rounded-full bg-gaufre/20 px-2 py-0.5 text-xs font-bold text-chocolat">
                        Nouveauté
                      </span>
                    )}
                    <span className="text-sm text-muted">
                      {CATEGORY_LABELS[w.category] ?? w.category}
                    </span>
                  </div>
                  <p className="mt-1 line-clamp-2 text-sm text-muted">
                    {w.ingredients}
                  </p>
                  {w.ingredientItems.length > 0 ? (
                    <p className="mt-1 text-xs text-chocolat/80">
                      Ingrédients :{" "}
                      {w.ingredientItems.map((i) => i.name).join(", ")}
                    </p>
                  ) : null}
                  <p className="mt-1 text-sm font-bold text-gaufre">
                    {w.price.toFixed(2).replace(".", ",")} €
                  </p>
                  </div>
                </div>
                <div className="flex shrink-0 gap-2 sm:pt-0">
                  <button
                    type="button"
                    onClick={() => startEdit(w)}
                    className="rounded-full border border-chocolat/20 px-4 py-1.5 text-sm font-medium text-chocolat hover:bg-cream"
                  >
                    Modifier
                  </button>
                  <button
                    type="button"
                    onClick={() => remove(w.id)}
                    className="rounded-full border border-red-200 bg-red-50 px-4 py-1.5 text-sm font-medium text-red-800 hover:bg-red-100"
                  >
                    Supprimer
                  </button>
                </div>
              </li>
            ))}
            {waffles.length === 0 && (
              <li className="rounded-2xl border border-dashed border-chocolat/20 p-8 text-center text-muted">
                Aucune gaufre pour le moment. Ajoutez-en une ci-dessus.
              </li>
            )}
          </ul>
          </>
        )}
      </div>
    </div>
  );
}
