"use client";

import Image from "next/image";
import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { ADMIN_API } from "@/lib/constants";
import { isUploadAssetPath } from "@/lib/image-url";
import type { SiteHoursRow } from "@/lib/site-content-defaults";

type FormState = {
  logoUrl: string;
  heroEyebrow: string;
  heroTitle: string;
  heroSubtitle: string;
  heroBackgroundImageUrl: string;
  heroTextOverImage: boolean;
  menuIntro: string;
  galleryIntro: string;
  uploadImageWidth: number;
  uploadImageHeight: number;
  hours: SiteHoursRow[];
};

export function AdminSiteContent() {
  const router = useRouter();
  const [form, setForm] = useState<FormState | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [uploadingLogo, setUploadingLogo] = useState(false);

  const load = useCallback(async () => {
    const res = await fetch(`${ADMIN_API}/site-content`, {
      credentials: "include",
    });
    if (res.status === 401) {
      router.replace("/admin/login");
      return;
    }
    const data = await res.json().catch(() => null);
    if (!data || typeof data !== "object") {
      setLoading(false);
      return;
    }
    const h = data.hours;
    const hours: SiteHoursRow[] = Array.isArray(h)
      ? h
          .filter(
            (x: unknown) =>
              x !== null &&
              typeof x === "object" &&
              typeof (x as { days?: string }).days === "string" &&
              typeof (x as { hours?: string }).hours === "string"
          )
          .map((x: { days: string; hours: string }) => ({
            days: x.days,
            hours: x.hours,
          }))
      : [];
    setForm({
      logoUrl: String(data.logoUrl ?? ""),
      heroEyebrow: String(data.heroEyebrow ?? ""),
      heroTitle: String(data.heroTitle ?? ""),
      heroSubtitle: String(data.heroSubtitle ?? ""),
      heroBackgroundImageUrl: String(data.heroBackgroundImageUrl ?? ""),
      heroTextOverImage: data.heroTextOverImage !== false,
      menuIntro: String(data.menuIntro ?? ""),
      galleryIntro: String(data.galleryIntro ?? ""),
      uploadImageWidth: Number(data.uploadImageWidth ?? 1920) || 1920,
      uploadImageHeight: Number(data.uploadImageHeight ?? 1080) || 1080,
      hours,
    });
    setLoading(false);
  }, [router]);

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

  function setHour(i: number, field: keyof SiteHoursRow, value: string) {
    setForm((f) => {
      if (!f) return f;
      const next = [...f.hours];
      next[i] = { ...next[i], [field]: value };
      return { ...f, hours: next };
    });
  }

  function addHourRow() {
    setForm((f) =>
      f ? { ...f, hours: [...f.hours, { days: "", hours: "" }] } : f
    );
  }

  function removeHourRow(i: number) {
    setForm((f) => {
      if (!f) return f;
      return { ...f, hours: f.hours.filter((_, j) => j !== i) };
    });
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!form) return;
    setSaving(true);
    try {
      const res = await fetch(`${ADMIN_API}/site-content`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(form),
      });
      if (res.status === 401) {
        router.replace("/admin/login");
        return;
      }
      const err = await res.json().catch(() => ({}));
      if (!res.ok) {
        alert(typeof err.error === "string" ? err.error : "Erreur");
        return;
      }
    } finally {
      setSaving(false);
    }
  }

  async function uploadImage(
    e: React.ChangeEvent<HTMLInputElement>,
    field: "logoUrl" | "heroBackgroundImageUrl",
    setBusy: (v: boolean) => void
  ) {
    const file = e.target.files?.[0];
    if (!file) return;
    setBusy(true);
    try {
      const fd = new FormData();
      fd.append("file", file);
      const res = await fetch(`${ADMIN_API}/upload`, {
        method: "POST",
        body: fd,
        credentials: "include",
      });
      if (res.status === 401) {
        router.replace("/admin/login");
        return;
      }
      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 ? { ...f, [field]: String(data.url) } : f));
      }
    } finally {
      setBusy(false);
      e.target.value = "";
    }
  }

  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">Textes du site</h1>
            <p className="text-sm text-muted">
              Accueil, menu, galerie et horaires affichés sur la page publique.
            </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>

        {loading || !form ? (
          <p className="text-muted">Chargement…</p>
        ) : (
          <form
            onSubmit={onSubmit}
            className="space-y-8 rounded-[2rem] border border-chocolat/10 bg-white p-6 shadow-[0_12px_40px_-12px_rgba(61,43,31,0.12)]"
          >
            <section>
              <h2 className="text-lg font-semibold text-chocolat">Logo</h2>
              <p className="mt-1 text-xs text-muted">
                Mascotte affichée à côté du nom dans l’en-tête du site.
              </p>
              <div className="mt-4 flex flex-col gap-2">
                <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={(e) => uploadImage(e, "logoUrl", setUploadingLogo)}
                      disabled={uploadingLogo}
                    />
                    {uploadingLogo ? "Envoi…" : "Choisir un fichier"}
                  </label>
                  <span className="text-xs text-muted">
                    ou chemin / URL ci-dessous
                  </span>
                </div>
                <input
                  type="text"
                  value={form.logoUrl}
                  onChange={(e) =>
                    setForm((f) => (f ? { ...f, logoUrl: e.target.value } : f))
                  }
                  placeholder="/logo.png ou /uploads/…"
                  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.logoUrl.trim() ? (
                  <div className="mt-2 flex items-start gap-3">
                    <div className="relative h-16 w-16 shrink-0 overflow-hidden rounded-xl border border-chocolat/10 bg-cream/50">
                      {form.logoUrl.startsWith("http") ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img
                          src={form.logoUrl}
                          alt=""
                          className="h-full w-full object-contain"
                        />
                      ) : (
                        <Image
                          src={form.logoUrl}
                          alt=""
                          fill
                          unoptimized={isUploadAssetPath(form.logoUrl)}
                          className="object-contain"
                          sizes="64px"
                        />
                      )}
                    </div>
                    <button
                      type="button"
                      onClick={() =>
                        setForm((f) => (f ? { ...f, logoUrl: "" } : f))
                      }
                      className="text-sm text-red-700 underline"
                    >
                      Retirer le logo
                    </button>
                  </div>
                ) : null}
              </div>
            </section>

            <section>
              <h2 className="text-lg font-semibold text-chocolat">
                Bloc accueil (héros)
              </h2>
              <p className="mt-1 text-xs text-muted">
                Image d’accueil et textes affichés sur la page publique.
              </p>
              <div className="mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <span className="text-sm font-medium text-chocolat">
                  L&apos;image au premier plan
                </span>
                <div
                  className="flex items-center gap-3"
                  role="group"
                  aria-label="Disposition image et texte"
                >
                  <span
                    className={`text-xs font-semibold uppercase tracking-wide ${
                      form.heroTextOverImage ? "text-muted" : "text-chocolat"
                    }`}
                  >
                    OFF
                  </span>
                  <button
                    type="button"
                    role="switch"
                    aria-checked={form.heroTextOverImage}
                    onClick={() =>
                      setForm((f) =>
                        f ? { ...f, heroTextOverImage: !f.heroTextOverImage } : f
                      )
                    }
                    className={`relative h-8 w-14 shrink-0 rounded-full transition-colors ${
                      form.heroTextOverImage ? "bg-gaufre" : "bg-chocolat/25"
                    }`}
                  >
                    <span
                      className={`absolute top-1 left-1 h-6 w-6 rounded-full bg-white shadow transition-transform ${
                        form.heroTextOverImage ? "translate-x-6" : "translate-x-0"
                      }`}
                    />
                  </button>
                  <span
                    className={`text-xs font-semibold uppercase tracking-wide ${
                      form.heroTextOverImage ? "text-chocolat" : "text-muted"
                    }`}
                  >
                    ON
                  </span>
                </div>
              </div>
              <p className="mt-1 text-xs text-muted">
                {form.heroTextOverImage
                  ? "ON : texte sur l’image (comme actuellement)."
                  : "OFF : image seule en haut, texte noir au-dessus du menu."}
              </p>
              <div className="mt-4 grid gap-4">
                <fieldset className="rounded-2xl border border-chocolat/12 bg-cream/30 p-4">
                  <legend className="px-1 text-sm font-semibold text-chocolat">
                    Texte au premier plan
                  </legend>
                  <div className="mt-3 grid gap-4">
                    <label className="flex flex-col gap-1 text-sm font-medium text-chocolat">
                      Surtitre (ex. Artisanal · Belge)
                      <input
                        value={form.heroEyebrow}
                        onChange={(e) =>
                          setForm((f) =>
                            f ? { ...f, heroEyebrow: e.target.value } : f
                          )
                        }
                        className="rounded-2xl border border-chocolat/15 bg-white 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">
                      Titre principal
                      <textarea
                        value={form.heroTitle}
                        onChange={(e) =>
                          setForm((f) =>
                            f ? { ...f, heroTitle: e.target.value } : f
                          )
                        }
                        rows={2}
                        className="resize-y rounded-2xl border border-chocolat/15 bg-white 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">
                      Texte sous le titre
                      <textarea
                        value={form.heroSubtitle}
                        onChange={(e) =>
                          setForm((f) =>
                            f ? { ...f, heroSubtitle: e.target.value } : f
                          )
                        }
                        rows={3}
                        className="resize-y rounded-2xl border border-chocolat/15 bg-white px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                      />
                    </label>
                  </div>
                </fieldset>
                <div className="flex flex-col gap-2">
                  <span className="text-sm font-medium text-chocolat">
                    Image de fond (accueil)
                  </span>
                  <div className="grid gap-3 sm:grid-cols-2">
                    <label className="flex flex-col gap-1 text-sm font-medium text-chocolat">
                      Redimensionnement upload (largeur)
                      <input
                        type="number"
                        min={320}
                        max={8000}
                        value={form.uploadImageWidth}
                        onChange={(e) =>
                          setForm((f) =>
                            f
                              ? {
                                  ...f,
                                  uploadImageWidth:
                                    Number(e.target.value || 0) || 0,
                                }
                              : f
                          )
                        }
                        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">
                      Redimensionnement upload (hauteur)
                      <input
                        type="number"
                        min={240}
                        max={8000}
                        value={form.uploadImageHeight}
                        onChange={(e) =>
                          setForm((f) =>
                            f
                              ? {
                                  ...f,
                                  uploadImageHeight:
                                    Number(e.target.value || 0) || 0,
                                }
                              : f
                          )
                        }
                        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>
                  <p className="text-xs text-muted">
                    Cette résolution est appliquée aux prochaines images envoyées
                    via l’admin (ex: 1920×1080).
                  </p>
                  <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={(e) =>
                          uploadImage(e, "heroBackgroundImageUrl", setUploading)
                        }
                        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.heroBackgroundImageUrl}
                    onChange={(e) =>
                      setForm((f) =>
                        f ? { ...f, heroBackgroundImageUrl: e.target.value } : f
                      )
                    }
                    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.heroBackgroundImageUrl.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.heroBackgroundImageUrl.startsWith("http") ? (
                          // eslint-disable-next-line @next/next/no-img-element
                          <img
                            src={form.heroBackgroundImageUrl}
                            alt=""
                            className="h-full w-full object-cover"
                          />
                        ) : (
                          <Image
                            src={form.heroBackgroundImageUrl}
                            alt=""
                            fill
                            unoptimized={isUploadAssetPath(
                              form.heroBackgroundImageUrl
                            )}
                            className="object-cover"
                            sizes="144px"
                          />
                        )}
                      </div>
                      <button
                        type="button"
                        onClick={() =>
                          setForm((f) =>
                            f ? { ...f, heroBackgroundImageUrl: "" } : f
                          )
                        }
                        className="text-sm text-red-700 underline"
                      >
                        Retirer l’image
                      </button>
                    </div>
                  ) : null}
                </div>
              </div>
            </section>

            <section>
              <h2 className="text-lg font-semibold text-chocolat">Section Menu</h2>
              <p className="mt-1 text-xs text-muted">
                Texte sous le titre « Menu ».
              </p>
              <label className="mt-4 flex flex-col gap-1 text-sm font-medium text-chocolat">
                Texte sous « Menu »
                <textarea
                  value={form.menuIntro}
                  onChange={(e) =>
                    setForm((f) =>
                      f ? { ...f, menuIntro: e.target.value } : f
                    )
                  }
                  rows={2}
                  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>
            </section>

            <section>
              <h2 className="text-lg font-semibold text-chocolat">
                Section Galerie
              </h2>
              <p className="mt-1 text-xs text-muted">
                Texte optionnel affiché sous le titre « Galerie », avant les
                photos.
              </p>
              <label className="mt-4 flex flex-col gap-1 text-sm font-medium text-chocolat">
                Texte sous « Galerie »
                <textarea
                  value={form.galleryIntro}
                  onChange={(e) =>
                    setForm((f) =>
                      f ? { ...f, galleryIntro: e.target.value } : f
                    )
                  }
                  rows={3}
                  placeholder="Laissez vide pour masquer ce bloc."
                  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>
            </section>

            <section>
              <h2 className="text-lg font-semibold text-chocolat">Horaires</h2>
              <p className="mt-1 text-xs text-muted">
                Affichés dans le pied de page. Supprimez toutes les lignes pour
                masquer le bloc horaires.
              </p>
              {form.hours.length === 0 ? (
                <p className="mt-4 rounded-2xl border border-dashed border-chocolat/20 bg-cream/40 px-4 py-6 text-sm text-muted">
                  Aucune ligne : le bloc « Horaires » sera masqué sur le site.
                </p>
              ) : (
                <ul className="mt-4 space-y-3">
                  {form.hours.map((row, i) => (
                    <li
                      key={i}
                      className="flex flex-col gap-2 rounded-2xl border border-chocolat/10 bg-cream/30 p-4 sm:flex-row sm:items-end"
                    >
                      <label className="flex min-w-0 flex-1 flex-col gap-1 text-sm font-medium text-chocolat">
                        Jours
                        <input
                          value={row.days}
                          onChange={(e) => setHour(i, "days", e.target.value)}
                          placeholder="Lun — Ven"
                          className="rounded-2xl border border-chocolat/15 bg-white px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                        />
                      </label>
                      <label className="flex min-w-0 flex-1 flex-col gap-1 text-sm font-medium text-chocolat">
                        Créneau
                        <input
                          value={row.hours}
                          onChange={(e) => setHour(i, "hours", e.target.value)}
                          placeholder="11h — 22h"
                          className="rounded-2xl border border-chocolat/15 bg-white px-4 py-2.5 outline-none ring-gaufre/40 focus:ring-2"
                        />
                      </label>
                      <button
                        type="button"
                        onClick={() => removeHourRow(i)}
                        className="shrink-0 rounded-full border border-red-200 bg-red-50 px-4 py-2 text-sm font-medium text-red-800"
                      >
                        Retirer
                      </button>
                    </li>
                  ))}
                </ul>
              )}
              <button
                type="button"
                onClick={addHourRow}
                className="mt-3 rounded-full border border-chocolat/20 px-4 py-2 text-sm font-medium text-chocolat hover:bg-cream"
              >
                Ajouter une ligne
              </button>
            </section>

            <div className="flex flex-wrap gap-3 border-t border-chocolat/10 pt-6">
              <button
                type="submit"
                disabled={saving || uploading || uploadingLogo}
                className="rounded-full bg-gaufre px-6 py-2.5 text-sm font-semibold text-chocolat shadow-md disabled:opacity-60"
              >
                {saving ? "Enregistrement…" : "Enregistrer"}
              </button>
            </div>
          </form>
        )}
      </div>
    </div>
  );
}
