"use client";

import { useEffect, useState, type FormEvent } from "react";
import { motion, useReducedMotion } from "framer-motion";
import type { Category } from "@/data/types";
import { Reveal } from "@/components/motion/Reveal";
import { MediaUploader } from "@/components/admin/MediaUploader";
import { Button } from "@/components/ui/Button";
import { useToast } from "@/context/toast-context";
import { easeSoft } from "@/lib/motion";

export default function AdminCategoriesPage() {
  const [categories, setCategories] = useState<Category[]>([]);
  const [name, setName] = useState("");
  const [slug, setSlug] = useState("");
  const [description, setDescription] = useState("");
  const [image, setImage] = useState("");
  const [editing, setEditing] = useState<Category | null>(null);
  const { toast } = useToast();
  const reduceMotion = useReducedMotion();

  const load = () =>
    fetch("/api/admin/categories", { credentials: "include" })
      .then((res) => res.json())
      .then((data: { categories?: Category[] }) =>
        setCategories(data.categories ?? []),
      );

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

  const onCreate = async (event: FormEvent) => {
    event.preventDefault();
    const res = await fetch("/api/admin/categories", {
      method: "POST",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name, slug, description, image }),
    });
    const data = (await res.json()) as { error?: string };
    if (!res.ok) {
      toast(data.error ?? "Could not create category", "error");
      return;
    }
    setName("");
    setSlug("");
    setDescription("");
    setImage("");
    await load();
    toast("Category created");
  };

  const onUpdate = async (event: FormEvent) => {
    event.preventDefault();
    if (!editing) return;
    const res = await fetch("/api/admin/categories", {
      method: "PATCH",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        id: editing.id,
        name: editing.name,
        description: editing.description,
        image: editing.image,
      }),
    });
    if (!res.ok) {
      toast("Could not update category", "error");
      return;
    }
    setEditing(null);
    await load();
    toast("Category updated");
  };

  const onDelete = async (id: string) => {
    if (!confirm("Delete this category?")) return;
    const res = await fetch(
      `/api/admin/categories?id=${encodeURIComponent(id)}`,
      { method: "DELETE", credentials: "include" },
    );
    const data = (await res.json()) as { error?: string };
    if (!res.ok) {
      toast(data.error ?? "Could not delete", "error");
      return;
    }
    await load();
    toast("Category deleted");
  };

  return (
    <div className="space-y-6">
      <Reveal>
        <h1 className="text-2xl font-semibold tracking-tight text-foreground">
          Categories
        </h1>
        <p className="mt-2 text-sm text-muted">
          Manage departments and upload cover images stored on your site.
        </p>
      </Reveal>

      <Reveal delay={0.06}>
        <motion.form
          onSubmit={onCreate}
          whileHover={
            reduceMotion
              ? undefined
              : { y: -1, transition: { duration: 0.28, ease: easeSoft } }
          }
          className="grid gap-4 rounded-2xl border border-border bg-card p-5 shadow-sm sm:grid-cols-2"
        >
          <h2 className="font-semibold text-foreground sm:col-span-2">
            Add category
          </h2>
          <label className="text-sm">
            <span className="mb-1 block text-muted">Name</span>
            <input
              required
              value={name}
              onChange={(event) => {
                setName(event.target.value);
                setSlug(
                  event.target.value
                    .toLowerCase()
                    .replace(/[^a-z0-9]+/g, "-")
                    .replace(/(^-|-$)/g, ""),
                );
              }}
              className="h-11 w-full rounded-xl border border-border bg-background px-3 text-foreground outline-none transition-colors focus:border-emerald-500/50"
            />
          </label>
          <label className="text-sm">
            <span className="mb-1 block text-muted">Slug</span>
            <input
              required
              value={slug}
              onChange={(event) => setSlug(event.target.value)}
              className="h-11 w-full rounded-xl border border-border bg-background px-3 text-foreground outline-none transition-colors focus:border-emerald-500/50"
            />
          </label>
          <label className="text-sm sm:col-span-2">
            <span className="mb-1 block text-muted">Description</span>
            <textarea
              value={description}
              onChange={(event) => setDescription(event.target.value)}
              rows={3}
              className="w-full rounded-xl border border-border bg-background px-3 py-3 text-foreground outline-none transition-colors focus:border-emerald-500/50"
            />
          </label>
          <div className="sm:col-span-2">
            <MediaUploader
              label="Category cover image"
              single
              max={1}
              folder="categories"
              images={image ? [image] : []}
              onChange={(images) => setImage(images[0] ?? "")}
            />
          </div>
          <div className="sm:col-span-2">
            <Button type="submit" className="h-11 rounded-xl">
              Create category
            </Button>
          </div>
        </motion.form>
      </Reveal>

      <div className="space-y-3">
        {categories.length === 0 ? (
          <motion.p
            initial={reduceMotion ? false : { opacity: 0, y: 8 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.4, ease: easeSoft }}
            className="rounded-2xl border border-dashed border-border px-4 py-10 text-center text-sm text-muted"
          >
            No categories yet.
          </motion.p>
        ) : (
          categories.map((category, index) => (
            <motion.div
              key={category.id}
              initial={
                reduceMotion
                  ? false
                  : { opacity: 0, y: 22, filter: "blur(4px)", scale: 0.985 }
              }
              whileInView={{
                opacity: 1,
                y: 0,
                filter: "blur(0px)",
                scale: 1,
              }}
              viewport={{
                once: false,
                amount: 0.35,
                margin: "-48px 0px -48px 0px",
              }}
              transition={{
                duration: 0.55,
                delay: reduceMotion ? 0 : Math.min((index % 8) * 0.03, 0.21),
                ease: easeSoft,
              }}
              whileHover={
                reduceMotion
                  ? undefined
                  : { y: -2, transition: { duration: 0.28, ease: easeSoft } }
              }
              className="rounded-2xl border border-border bg-card p-4 shadow-sm transition-colors"
            >
              {editing?.id === category.id ? (
                <form onSubmit={onUpdate} className="space-y-3">
                  <input
                    value={editing.name}
                    onChange={(event) =>
                      setEditing({ ...editing, name: event.target.value })
                    }
                    className="h-11 w-full rounded-xl border border-border bg-background px-3 text-foreground outline-none transition-colors focus:border-emerald-500/50"
                  />
                  <textarea
                    value={editing.description}
                    onChange={(event) =>
                      setEditing({
                        ...editing,
                        description: event.target.value,
                      })
                    }
                    rows={3}
                    className="w-full rounded-xl border border-border bg-background px-3 py-3 text-foreground outline-none transition-colors focus:border-emerald-500/50"
                  />
                  <MediaUploader
                    label="Cover image"
                    single
                    max={1}
                    folder="categories"
                    images={editing.image ? [editing.image] : []}
                    onChange={(images) =>
                      setEditing({ ...editing, image: images[0] ?? "" })
                    }
                  />
                  <div className="flex gap-2">
                    <Button type="submit" className="h-10 rounded-xl">
                      Save
                    </Button>
                    <button
                      type="button"
                      onClick={() => setEditing(null)}
                      className="h-10 rounded-xl border border-border px-4 text-sm text-foreground transition-colors hover:bg-surface"
                    >
                      Cancel
                    </button>
                  </div>
                </form>
              ) : (
                <div className="flex flex-wrap items-center gap-4">
                  <motion.span
                    whileHover={reduceMotion ? undefined : { scale: 1.03 }}
                    transition={{ duration: 0.3, ease: easeSoft }}
                    className="relative h-14 w-20 overflow-hidden rounded-lg bg-surface"
                  >
                    {/* eslint-disable-next-line @next/next/no-img-element */}
                    <img
                      src={category.image}
                      alt=""
                      className="h-full w-full object-cover"
                    />
                  </motion.span>
                  <div className="min-w-0 flex-1">
                    <p className="font-medium text-foreground">
                      {category.name}
                    </p>
                    <p className="text-xs text-muted">
                      {category.slug} · {category.productCount} products
                    </p>
                  </div>
                  <div className="flex gap-2">
                    <motion.button
                      type="button"
                      whileHover={reduceMotion ? undefined : { y: -1 }}
                      whileTap={reduceMotion ? undefined : { scale: 0.97 }}
                      onClick={() => setEditing(category)}
                      className="h-9 rounded-lg border border-border px-3 text-xs text-foreground transition-colors hover:bg-surface"
                    >
                      Edit
                    </motion.button>
                    <motion.button
                      type="button"
                      whileHover={reduceMotion ? undefined : { y: -1 }}
                      whileTap={reduceMotion ? undefined : { scale: 0.97 }}
                      onClick={() => void onDelete(category.id)}
                      className="h-9 rounded-lg border border-border px-3 text-xs text-red-600 transition-colors hover:bg-red-500/10 dark:text-red-300"
                    >
                      Delete
                    </motion.button>
                  </div>
                </div>
              )}
            </motion.div>
          ))
        )}
      </div>
    </div>
  );
}
