"use client";

import Image from "next/image";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import type { GalleryImage } from "@/generated/prisma/client";
import { isUploadAssetPath } from "@/lib/image-url";
import { ADMIN_API } from "@/lib/constants";

export function AdminGallery() {
  const router = useRouter();
  const [items, setItems] = useState<GalleryImage[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState({
    imageUrl: "",
    alt: "",
    sortOrder: "0",
  });

  const load = useCallback(async () => {
    const res = await fetch(`${ADMIN_API}/gallery`, { credentials: "include" });
    if (res.status === 401) {
      router.replace("/admin/login");
      return;
    }
    const data = await res.json();
    setItems(Array.isArray(data) ? data : []);
    setLoading(false);
  }, [router]);

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

  function resetForm() {
    setEditingId(null);
    setForm({ imageUrl: "", alt: "", sortOrder: "0" });
  }

  function startEdit(g: GalleryImage) {
    setEditingId(g.id);
    setForm({
      imageUrl: g.imageUrl,
      alt: g.alt,
      sortOrder: String(g.sortOrder),
    });
  }

  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 sortOrder = parseInt(form.sortOrder, 10);
    if (Number.isNaN(sortOrder)) return;
    setSaving(true);
    try {
      const body = {
        imageUrl: form.imageUrl.trim() || null,
        alt: form.alt.trim(),
        sortOrder,
      };
      if (editingId) {
        const res = await fetch(`${ADMIN_API}/gallery/${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) {
          const err = await res.json().catch(() => ({}));
          alert(typeof err.error === "string" ? err.error : "Erreur");
          return;
        }
      } else {
        const res = await fetch(`${ADMIN_API}/gallery`, {
          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) {
          const err = await res.json().catch(() => ({}));
          alert(typeof err.error === "string" ? err.error : "Erreur");
          return;
        }
      }
      resetForm();
      await load();
    } finally {
      setSaving(false);
    }
  }

  async function remove(id: string) {
    if (!confirm("Supprimer cette photo de la galerie ?")) return;
    const res = await fetch(`${ADMIN_API}/gallery/${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">Galerie du site</h1>
            <p className="text-sm text-muted">
              Ordre d’affichage (nombre le plus petit en premier). Sur la page
              d’accueil, jusqu’à 3 photos visibles ; défilement toutes les 5 s si
              plus de 3 images.
            </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 photo" : "Ajouter une photo"}
          </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">
              Texte alternatif (accessibilité)
              <input
                value={form.alt}
                onChange={(e) => setForm((f) => ({ ...f, alt: 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">
              Ordre (0 = premier)
              <input
                type="text"
                inputMode="numeric"
                value={form.sortOrder}
                onChange={(e) =>
                  setForm((f) => ({ ...f, sortOrder: 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>
            <div className="flex flex-col gap-2 sm:col-span-2">
              <span className="text-sm font-medium text-chocolat">Image</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 chemin / URL ci-dessous</span>
              </div>
              <input
                type="text"
                value={form.imageUrl}
                onChange={(e) =>
                  setForm((f) => ({ ...f, imageUrl: e.target.value }))
                }
                required
                placeholder="/uploads/… ou https://…"
                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"
              />
              {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=""
                        className="h-full w-full object-cover"
                      />
                    ) : (
                      <Image
                        src={form.imageUrl}
                        alt=""
                        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 l’image
                  </button>
                </div>
              ) : null}
            </div>
          </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>
        ) : (
          <ul className="space-y-3">
            {items.map((g) => (
              <li
                key={g.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">
                  <div className="relative h-20 w-28 shrink-0 overflow-hidden rounded-xl border border-chocolat/10 bg-chocolat/5">
                    {g.imageUrl.startsWith("http") ? (
                      // eslint-disable-next-line @next/next/no-img-element
                      <img
                        src={g.imageUrl}
                        alt=""
                        className="h-full w-full object-cover"
                      />
                    ) : (
                      <Image
                        src={g.imageUrl}
                        alt=""
                        fill
                        unoptimized={isUploadAssetPath(g.imageUrl)}
                        className="object-cover"
                        sizes="112px"
                      />
                    )}
                  </div>
                  <div className="min-w-0">
                    <p className="font-medium text-chocolat">{g.alt}</p>
                    <p className="mt-1 truncate text-xs text-muted">{g.imageUrl}</p>
                    <p className="mt-1 text-sm text-muted">Ordre : {g.sortOrder}</p>
                  </div>
                </div>
                <div className="flex shrink-0 gap-2">
                  <button
                    type="button"
                    onClick={() => startEdit(g)}
                    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(g.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>
            ))}
            {items.length === 0 && (
              <li className="rounded-2xl border border-dashed border-chocolat/20 p-8 text-center text-muted">
                Aucune image. Ajoutez-en une ci-dessus.
              </li>
            )}
          </ul>
        )}
      </div>
    </div>
  );
}
