import { useEffect, useState } from "react";
import { X } from "lucide-react";
import { useCreateCategory, useUpdateCategory } from "../hooks/useCategories";
import { useToast } from "../context/ToastContext";
import type { Category, CategoryType } from "../api/types";

interface Props {
  isOpen: boolean;
  onClose: () => void;
  category?: Category;
}

interface FormState {
  name: string;
  type: CategoryType;
  color: string;
  icon: string;
}

const DEFAULT_FORM: FormState = {
  name: "",
  type: "expense",
  color: "#6366f1",
  icon: "",
};

export default function CategoryModal({ isOpen, onClose, category }: Props) {
  const createMutation = useCreateCategory();
  const updateMutation = useUpdateCategory();
  const { addToast } = useToast();

  const [form, setForm] = useState<FormState>(DEFAULT_FORM);
  const [errors, setErrors] = useState<Partial<Record<keyof FormState, string>>>({});

  const isEditing = !!category;
  const isDefault = category?.is_default ?? false;
  const isPending = createMutation.isPending || updateMutation.isPending;

  useEffect(() => {
    if (category) {
      setForm({
        name: category.name,
        type: category.type,
        color: category.color ?? "#6366f1",
        icon: category.icon ?? "",
      });
    } else {
      setForm(DEFAULT_FORM);
    }
    setErrors({});
  }, [category, isOpen]);

  function set<K extends keyof FormState>(key: K, value: FormState[K]) {
    setForm((prev) => ({ ...prev, [key]: value }));
    if (errors[key]) setErrors((e) => ({ ...e, [key]: undefined }));
  }

  function validate(): boolean {
    const errs: Partial<Record<keyof FormState, string>> = {};
    if (!form.name.trim()) errs.name = "Nom requis";
    setErrors(errs);
    return Object.keys(errs).length === 0;
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!validate()) return;

    if (isEditing && category) {
      updateMutation.mutate(
        {
          id: category.id,
          payload: {
            name: form.name.trim(),
            color: form.color,
            icon: form.icon || undefined,
          },
        },
        {
          onSuccess: () => {
            addToast({ type: "success", message: "Catégorie modifiée" });
            onClose();
          },
          onError: () =>
            addToast({ type: "error", message: "Erreur lors de la modification" }),
        },
      );
    } else {
      createMutation.mutate(
        {
          name: form.name.trim(),
          type: form.type,
          color: form.color,
          icon: form.icon || undefined,
        },
        {
          onSuccess: () => {
            addToast({ type: "success", message: "Catégorie créée" });
            onClose();
          },
          onError: () =>
            addToast({ type: "error", message: "Erreur lors de la création" }),
        },
      );
    }
  }

  if (!isOpen) return null;

  const CATEGORY_TYPES: { value: CategoryType; label: string }[] = [
    { value: "expense", label: "Dépense" },
    { value: "income", label: "Revenu" },
    { value: "both", label: "Les deux" },
  ];

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4"
      onClick={onClose}
    >
      <div
        className="w-full max-w-md rounded-xl bg-white shadow-xl"
        onClick={(e) => e.stopPropagation()}
      >
        {/* Header */}
        <div className="flex items-center justify-between border-b px-5 py-4">
          <h2 className="text-base font-semibold text-slate-800">
            {isEditing ? "Modifier la catégorie" : "Nouvelle catégorie"}
          </h2>
          <button
            onClick={onClose}
            className="text-slate-400 hover:text-slate-700"
            aria-label="Fermer"
          >
            <X size={18} />
          </button>
        </div>

        <form onSubmit={handleSubmit} className="space-y-4 p-5">
          {isDefault && (
            <p className="rounded-lg bg-amber-50 px-3 py-2 text-xs text-amber-700">
              Les catégories par défaut ne peuvent pas être modifiées en type.
            </p>
          )}

          {/* Name */}
          <div>
            <label
              htmlFor="cat-name"
              className="mb-1.5 block text-sm font-medium text-slate-700"
            >
              Nom
            </label>
            <input
              id="cat-name"
              type="text"
              value={form.name}
              onChange={(e) => set("name", e.target.value)}
              placeholder="Ex. : Alimentation"
              className={`w-full rounded-lg border px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-primary/30 ${
                errors.name ? "border-red-400" : "border-slate-200"
              }`}
            />
            {errors.name && (
              <p className="mt-1 text-xs text-red-500">{errors.name}</p>
            )}
          </div>

          {/* Type */}
          <div>
            <label
              htmlFor="cat-type"
              className="mb-1.5 block text-sm font-medium text-slate-700"
            >
              Type
            </label>
            <select
              id="cat-type"
              value={form.type}
              onChange={(e) => set("type", e.target.value as CategoryType)}
              disabled={isDefault || isEditing}
              className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-primary/30 disabled:bg-slate-50 disabled:text-slate-400"
            >
              {CATEGORY_TYPES.map((t) => (
                <option key={t.value} value={t.value}>
                  {t.label}
                </option>
              ))}
            </select>
          </div>

          {/* Color */}
          <div>
            <label
              htmlFor="cat-color"
              className="mb-1.5 block text-sm font-medium text-slate-700"
            >
              Couleur
            </label>
            <div className="flex items-center gap-3">
              <input
                id="cat-color"
                type="color"
                value={form.color}
                onChange={(e) => set("color", e.target.value)}
                className="h-9 w-14 cursor-pointer rounded border border-slate-200 p-0.5"
              />
              <span className="text-sm text-slate-500">{form.color}</span>
            </div>
          </div>

          {/* Icon */}
          <div>
            <label
              htmlFor="cat-icon"
              className="mb-1.5 block text-sm font-medium text-slate-700"
            >
              Icône{" "}
              <span className="font-normal text-slate-400">(optionnel)</span>
            </label>
            <input
              id="cat-icon"
              type="text"
              value={form.icon}
              onChange={(e) => set("icon", e.target.value)}
              placeholder="Ex. : shopping-cart"
              className="w-full rounded-lg border border-slate-200 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-primary/30"
            />
          </div>

          {/* Actions */}
          <div className="flex justify-end gap-3 pt-2">
            <button
              type="button"
              onClick={onClose}
              className="rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50"
            >
              Annuler
            </button>
            <button
              type="submit"
              disabled={isPending}
              className="rounded-lg bg-primary px-4 py-2 text-sm font-medium text-white hover:bg-primary/90 disabled:opacity-50"
            >
              {isPending
                ? "Enregistrement…"
                : isEditing
                  ? "Modifier"
                  : "Créer"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
