
"use client";

import { useEffect, useState } from "react";
import {
  LuPlus,
  LuSearch,
  LuPencil,
  LuTrash2,
  LuX,
  LuCheck,
  LuSparkles,
  LuStethoscope,
  LuHeartPulse,
  LuBaby,
  LuPill,
  LuHandHeart,
  LuPillBottle,
} from "react-icons/lu";

const API_URL = "http://localhost:5000/api";

const categoryIcons = {
  LuSparkles,
  LuStethoscope,
  LuHeartPulse,
  LuBaby,
  LuPill,
  LuHandHeart,
  LuPillBottle,
};

type IconName = keyof typeof categoryIcons;

interface Category {
  id: number;
  name: string;
  slug: string;
  icon: IconName;
  status: "active" | "inactive";
  sort_order: number;
  product_count: number;
}

interface CategoryForm {
  name: string;
  slug: string;
  icon: IconName;
  status: "active" | "inactive";
  sort_order: number;
}

const emptyForm: CategoryForm = {
  name: "",
  slug: "",
  icon: "LuPill",
  status: "active",
  sort_order: 0,
};

export default function CategoriesPage() {
  const [categories, setCategories] = useState<Category[]>([]);
  const [search, setSearch] = useState("");
  const [loading, setLoading] = useState(true);

  const [showModal, setShowModal] = useState(false);
  const [editingId, setEditingId] = useState<number | null>(null);

  const [form, setForm] = useState<CategoryForm>(emptyForm);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    fetchCategories();
  }, []);

  async function fetchCategories() {
    try {
      setLoading(true);

      const response = await fetch(`${API_URL}/categories`);

      if (!response.ok) {
        throw new Error("Failed to fetch categories");
      }

      const data = await response.json();

      setCategories(data);
    } catch (error) {
      console.error("Fetch categories error:", error);
    } finally {
      setLoading(false);
    }
  }

  function openAddModal() {
    setEditingId(null);
    setForm(emptyForm);
    setShowModal(true);
  }

  async function openEditModal(id: number) {
    try {
      const response = await fetch(`${API_URL}/categories/${id}`);

      if (!response.ok) {
        throw new Error("Failed to fetch category");
      }

      const data = await response.json();

      setEditingId(id);

      setForm({
        name: data.name,
        slug: data.slug,
        icon: data.icon,
        status: data.status,
        sort_order: data.sort_order,
      });

      setShowModal(true);
    } catch (error) {
      console.error("Fetch category error:", error);
      alert("Failed to load category.");
    }
  }

  function closeModal() {
    if (saving) return;

    setShowModal(false);
    setEditingId(null);
    setForm(emptyForm);
  }

  function handleNameChange(value: string) {
    setForm((previous) => ({
      ...previous,
      name: value,
      slug:
        editingId === null
          ? value
              .toLowerCase()
              .trim()
              .replace(/[^a-z0-9]+/g, "-")
              .replace(/^-+|-+$/g, "")
          : previous.slug,
    }));
  }

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault();

    if (!form.name.trim()) {
      alert("Please enter category name.");
      return;
    }

    if (!form.slug.trim()) {
      alert("Please enter category slug.");
      return;
    }

    try {
      setSaving(true);

      const url = editingId
        ? `${API_URL}/categories/${editingId}`
        : `${API_URL}/categories`;

      const method = editingId ? "PUT" : "POST";

      const response = await fetch(url, {
        method,
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          ...form,
          name: form.name.trim(),
          slug: form.slug.trim(),
        }),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || "Something went wrong");
      }

      closeModal();

      await fetchCategories();
    } catch (error) {
      console.error("Save category error:", error);

      alert(
        error instanceof Error
          ? error.message
          : "Failed to save category."
      );
    } finally {
      setSaving(false);
    }
  }

  async function deleteCategory(id: number) {
    const category = categories.find((item) => item.id === id);

    if (!category) return;

    const confirmed = window.confirm(
      `Are you sure you want to delete "${category.name}"?`
    );

    if (!confirmed) return;

    try {
      const response = await fetch(`${API_URL}/categories/${id}`, {
        method: "DELETE",
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || "Failed to delete category");
      }

      await fetchCategories();
    } catch (error) {
      console.error("Delete category error:", error);

      alert(
        error instanceof Error
          ? error.message
          : "Failed to delete category."
      );
    }
  }

  const filteredCategories = categories.filter((category) =>
    category.name.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <div>
      {/* PAGE HEADER */}
      <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-gray-800">
            Categories
          </h1>

          <p className="mt-1 text-sm text-gray-400">
            Manage pharmacy product categories.
          </p>
        </div>

        <button
          type="button"
          onClick={openAddModal}
          className="inline-flex items-center justify-center gap-2 rounded-xl bg-[#B570D4] px-5 py-3 text-sm font-semibold text-white transition hover:opacity-90"
        >
          <LuPlus size={18} />
          Add Category
        </button>
      </div>

      {/* SEARCH */}
      <div className="mb-5 rounded-2xl border border-[#EAECEF] bg-white p-4">
        <div className="relative max-w-md">
          <LuSearch
            size={19}
            className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
          />

          <input
            type="text"
            value={search}
            onChange={(event) => setSearch(event.target.value)}
            placeholder="Search categories..."
            className="w-full rounded-xl border border-[#E5E7EB] py-3 pl-10 pr-4 text-sm outline-none transition focus:border-[#B570D4]"
          />
        </div>
      </div>

      {/* TABLE */}
      <div className="overflow-hidden rounded-2xl border border-[#EAECEF] bg-white">
        <div className="overflow-x-auto">
          <table className="w-full min-w-[750px]">
            <thead>
              <tr className="border-b border-[#EAECEF] bg-[#FAFAFB]">
                <th className="px-6 py-4 text-left text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Category
                </th>

                <th className="px-6 py-4 text-left text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Slug
                </th>

                <th className="px-6 py-4 text-left text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Products
                </th>

                <th className="px-6 py-4 text-left text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Status
                </th>

                <th className="px-6 py-4 text-right text-xs font-semibold uppercase tracking-wide text-gray-400">
                  Actions
                </th>
              </tr>
            </thead>

            <tbody>
              {loading ? (
                <tr>
                  <td
                    colSpan={5}
                    className="px-6 py-16 text-center text-sm text-gray-400"
                  >
                    Loading categories...
                  </td>
                </tr>
              ) : filteredCategories.length === 0 ? (
                <tr>
                  <td
                    colSpan={5}
                    className="px-6 py-16 text-center"
                  >
                    <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-[#F8F1FB] text-[#B570D4]">
                      <LuTagsIcon />
                    </div>

                    <p className="mt-4 text-sm font-medium text-gray-600">
                      {search
                        ? "No categories found"
                        : "No categories yet"}
                    </p>

                    {!search && (
                      <p className="mt-1 text-xs text-gray-400">
                        Click "Add Category" to create your first
                        category.
                      </p>
                    )}
                  </td>
                </tr>
              ) : (
                filteredCategories.map((category) => {
                  const Icon =
                    categoryIcons[category.icon] || LuPill;

                  return (
                    <tr
                      key={category.id}
                      className="border-b border-[#F0F0F2] last:border-b-0 hover:bg-[#FCFCFD]"
                    >
                      <td className="px-6 py-4">
                        <div className="flex items-center gap-3">
                          <div className="flex h-10 w-10 items-center justify-center rounded-xl bg-[#F8F1FB] text-[#B570D4]">
                            <Icon size={20} strokeWidth={1.7} />
                          </div>

                          <span className="text-sm font-semibold text-gray-700">
                            {category.name}
                          </span>
                        </div>
                      </td>

                      <td className="px-6 py-4">
                        <span className="text-sm text-gray-400">
                          {category.slug}
                        </span>
                      </td>

                      <td className="px-6 py-4">
                        <span className="text-sm font-medium text-gray-700">
                          {category.product_count}
                        </span>
                      </td>

                      <td className="px-6 py-4">
                        {category.status === "active" ? (
                          <span className="inline-flex items-center gap-1.5 rounded-full bg-green-50 px-3 py-1 text-xs font-semibold text-green-600">
                            <LuCheck size={13} />
                            Active
                          </span>
                        ) : (
                          <span className="inline-flex items-center gap-1.5 rounded-full bg-gray-100 px-3 py-1 text-xs font-semibold text-gray-500">
                            Inactive
                          </span>
                        )}
                      </td>

                      <td className="px-6 py-4">
                        <div className="flex justify-end gap-2">
                          <button
                            type="button"
                            onClick={() =>
                              openEditModal(category.id)
                            }
                            className="flex h-9 w-9 items-center justify-center rounded-lg border border-[#EAECEF] text-gray-500 transition hover:border-[#B570D4] hover:text-[#B570D4]"
                            title="Edit"
                          >
                            <LuPencil size={16} />
                          </button>

                          <button
                            type="button"
                            onClick={() =>
                              deleteCategory(category.id)
                            }
                            className="flex h-9 w-9 items-center justify-center rounded-lg border border-[#EAECEF] text-gray-500 transition hover:border-red-200 hover:bg-red-50 hover:text-red-500"
                            title="Delete"
                          >
                            <LuTrash2 size={16} />
                          </button>
                        </div>
                      </td>
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>

      {/* MODAL */}
      {showModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
          <div className="w-full max-w-lg rounded-2xl bg-white shadow-2xl">
            {/* MODAL HEADER */}
            <div className="flex items-center justify-between border-b border-[#EAECEF] px-6 py-5">
              <div>
                <h2 className="text-lg font-bold text-gray-800">
                  {editingId
                    ? "Edit Category"
                    : "Add Category"}
                </h2>

                <p className="mt-1 text-xs text-gray-400">
                  {editingId
                    ? "Update category information."
                    : "Create a new pharmacy category."}
                </p>
              </div>

              <button
                type="button"
                onClick={closeModal}
                className="flex h-9 w-9 items-center justify-center rounded-lg text-gray-400 transition hover:bg-gray-100 hover:text-gray-700"
              >
                <LuX size={19} />
              </button>
            </div>

            {/* FORM */}
            <form onSubmit={handleSubmit}>
              <div className="space-y-5 p-6">
                {/* NAME */}
                <div>
                  <label className="mb-2 block text-sm font-medium text-gray-700">
                    Category Name
                  </label>

                  <input
                    type="text"
                    value={form.name}
                    onChange={(event) =>
                      handleNameChange(event.target.value)
                    }
                    placeholder="e.g. OTC Medicine"
                    className="w-full rounded-xl border border-[#E5E7EB] px-4 py-3 text-sm outline-none focus:border-[#B570D4]"
                  />
                </div>

                {/* SLUG */}
                <div>
                  <label className="mb-2 block text-sm font-medium text-gray-700">
                    Slug
                  </label>

                  <input
                    type="text"
                    value={form.slug}
                    onChange={(event) =>
                      setForm((previous) => ({
                        ...previous,
                        slug: event.target.value,
                      }))
                    }
                    placeholder="otc-medicine"
                    className="w-full rounded-xl border border-[#E5E7EB] px-4 py-3 text-sm outline-none focus:border-[#B570D4]"
                  />
                </div>

                {/* ICON */}
                <div>
                  <label className="mb-2 block text-sm font-medium text-gray-700">
                    Category Icon
                  </label>

                  <div className="grid grid-cols-4 gap-2 sm:grid-cols-7">
                    {(
                      Object.keys(categoryIcons) as IconName[]
                    ).map((iconName) => {
                      const Icon = categoryIcons[iconName];

                      const selected =
                        form.icon === iconName;

                      return (
                        <button
                          key={iconName}
                          type="button"
                          onClick={() =>
                            setForm((previous) => ({
                              ...previous,
                              icon: iconName,
                            }))
                          }
                          className={`flex h-12 items-center justify-center rounded-xl border transition ${
                            selected
                              ? "border-[#B570D4] bg-[#F8F1FB] text-[#B570D4]"
                              : "border-[#EAECEF] text-gray-400 hover:border-[#D9B8E8] hover:text-[#B570D4]"
                          }`}
                          title={iconName}
                        >
                          <Icon size={21} />
                        </button>
                      );
                    })}
                  </div>
                </div>

                {/* STATUS + SORT */}
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <label className="mb-2 block text-sm font-medium text-gray-700">
                      Status
                    </label>

                    <select
                      value={form.status}
                      onChange={(event) =>
                        setForm((previous) => ({
                          ...previous,
                          status: event.target.value as
                            | "active"
                            | "inactive",
                        }))
                      }
                      className="w-full rounded-xl border border-[#E5E7EB] bg-white px-4 py-3 text-sm outline-none focus:border-[#B570D4]"
                    >
                      <option value="active">Active</option>
                      <option value="inactive">
                        Inactive
                      </option>
                    </select>
                  </div>

                  <div>
                    <label className="mb-2 block text-sm font-medium text-gray-700">
                      Sort Order
                    </label>

                    <input
                      type="number"
                      min="0"
                      value={form.sort_order}
                      onChange={(event) =>
                        setForm((previous) => ({
                          ...previous,
                          sort_order:
                            Number(event.target.value) || 0,
                        }))
                      }
                      className="w-full rounded-xl border border-[#E5E7EB] px-4 py-3 text-sm outline-none focus:border-[#B570D4]"
                    />
                  </div>
                </div>
              </div>

              {/* MODAL FOOTER */}
              <div className="flex justify-end gap-3 border-t border-[#EAECEF] px-6 py-4">
                <button
                  type="button"
                  onClick={closeModal}
                  disabled={saving}
                  className="rounded-xl border border-[#EAECEF] px-5 py-2.5 text-sm font-medium text-gray-600 transition hover:bg-gray-50"
                >
                  Cancel
                </button>

                <button
                  type="submit"
                  disabled={saving}
                  className="rounded-xl bg-[#B570D4] px-5 py-2.5 text-sm font-semibold text-white transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {saving
                    ? "Saving..."
                    : editingId
                    ? "Update Category"
                    : "Create Category"}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

function LuTagsIcon() {
  return <LuSparkles size={22} strokeWidth={1.7} />;
}
