"use client";

import { useState, useEffect, useCallback, useMemo } from "react";
import { Button } from "../../../../../../src/components/ui/button";
import { Input } from "../../../../../../src/components/ui/input";
import { Label } from "../../../../../../src/components/ui/label";
import { Plus, Search, ChevronLeft, ChevronRight as ChevronRightIcon, X } from "lucide-react";
import { toast } from "sonner";
import { useDebounce } from "../../../../../../src/hooks/useDebounce";
import CategoryFormDialog from "./CategoryFormDialog";
import CategoryViewDialog from "./CategoryViewDialog";
import CategoryTable from "./CategoryTable";
import ImagePreviewModal from "../../../../../../src/components/ImagePreview/ImagePreviewer";
interface Category {
  _id: string;
  name: string;
  slug: string;
  description?: string;
  image?: string;
  parent?: { _id: string; name: string; slug: string; };
  level: number;
  isActive: boolean;
  isevent?: boolean;
  createdAt: string;
}

const initialFormData = {
  name: "",
  description: "",
  parent: "",
  image: "",
  isActive: true,
  isEvent: false,
};

export default function CategoriesManagement() {
  const [categories, setCategories] = useState<Category[]>([]);
  const [loading, setLoading] = useState(true);
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [isViewDialogOpen, setIsViewDialogOpen] = useState(false);
  const [viewingCategory, setViewingCategory] = useState<Category | null>(null);
  const [editingCategory, setEditingCategory] = useState<Category | null>(null);
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);
  const [limit, setLimit] = useState(10);
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [sortField, setSortField] = useState<"name" | "createdAt">("createdAt");
  const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");
  const [pagination, setPagination] = useState({ total: 0, pages: 0, page: 1, limit: 10 });
  const [previewOpen, setPreviewOpen] = useState(false);
  const [activeIndex, setActiveIndex] = useState(0);
  const [formData, setFormData] = useState(initialFormData);
  const [submitting, setSubmitting] = useState(false);
  const [eventFilter, setEventFilter] = useState<'all' | 'true' | 'false'>('all');

  const debouncedSearch = useDebounce(search, 500);  

  useEffect(() => {
    return () => {
      if (formData.image?.startsWith("blob:")) {
        URL.revokeObjectURL(formData.image);
      }
    };
  }, [formData.image]);

  const fetchCategories = useCallback(async () => {
    try {
      setLoading(true);
      const params = new URLSearchParams({
        page: page.toString(),
        limit: limit.toString(),
        level: '1',
        sort: sortField,
        order: sortOrder,
        ...(debouncedSearch && { search: debouncedSearch }),
        ...(eventFilter !== 'all' && { isEvent: eventFilter }),
      });
      const response = await fetch(`/api/categories?${params}`);
      const result = await response.json();
      if (result.success) {
        setCategories(result.data);
        setPagination(result.pagination);
      } else {
        toast.error("Failed to fetch categories");
      }
    } catch {
      toast.error("Error fetching categories");
    } finally {
      setLoading(false);
    }
  }, [page, limit, sortField, sortOrder, debouncedSearch, eventFilter]);

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

  const resetForm = useCallback(() => {
    setFormData(initialFormData);
    setImageFile(null);
  }, []);

  const handleSearch = useCallback((value: string) => {
    setSearch(value);
    setPage(1);
  }, []);

  const handleLimitChange = useCallback((value: string) => {
    setLimit(parseInt(value));
    setPage(1);
  }, []);

  const handleEventFilterChange = useCallback((value: 'all' | 'true' | 'false') => {
    setEventFilter(value);
    setPage(1);
  }, []);

  const handleSort = useCallback((field: "name" | "createdAt") => {
    if (sortField === field) {
      setSortOrder(o => o === "asc" ? "desc" : "asc");
    } else {
      setSortField(field);
      setSortOrder(field === "name" ? "asc" : "desc");
    }
    setPage(1);
  }, [sortField]);

  const isValidCategoryName = useCallback((name: string) => {
    return /^[A-Za-z\s]+$/.test(name);
  }, []);

  const handleView = useCallback((category: Category) => {
    setViewingCategory(category);
    setIsViewDialogOpen(true);
  }, []);

  const handleEdit = useCallback((category: Category) => {
    setEditingCategory(category);
    setFormData({
      name: category.name,
      description: category.description || "",
      parent: category.parent?._id || "",
      image: category.image || "",
      isActive: category.isActive,
      isEvent: category.isevent ?? false,
    });
    setImageFile(null);
    setIsDialogOpen(true);
  }, []);

  const handleDelete = useCallback(async (categoryId: string) => {
    if (!confirm("Are you sure you want to delete this category?")) return;
    try {
      const response = await fetch(`/api/categories/${categoryId}`, { method: "DELETE" });
      const result = await response.json();
      if (result.success) {
        toast.success("Category deleted successfully");
        // If deleting the last item on the current page,
        // move to previous page
        if (categories.length === 1 && page > 1) {
          setPage((prev) => prev - 1);
        } else {
          fetchCategories();
        }
      } else {
        toast.error(result.error || "Failed to delete category");
      }
    } catch {
      toast.error("Error deleting category");
    }
  }, [fetchCategories, categories.length, page]);

  const handleSubmit = useCallback(async (e: React.FormEvent) => {
    e.preventDefault();
    setSubmitting(true);

    try {
      const url = editingCategory ? `/api/categories/${editingCategory._id}` : "/api/categories";
      const method = editingCategory ? "PUT" : "POST";
      const form = new FormData();
      form.append("name", formData.name);
      form.append("description", formData.description);
      form.append("isActive", String(formData.isActive));
      form.append("isEvent", String(formData.isEvent));
      if (formData.parent) form.append("parent", formData.parent);
      if (imageFile) form.append("image", imageFile);

      const response = await fetch(url, { method, body: form });
      const result = await response.json();

      if (result.success) {
        toast.success(editingCategory ? "Category updated successfully" : "Category created successfully");
        setIsDialogOpen(false);
        setEditingCategory(null);
        resetForm();
        fetchCategories();
      } else {
        toast.error(result.error || "Failed to save category");
      }
    } catch {
      toast.error("Error saving category");
    } finally {
      setSubmitting(false);
    }
  }, [editingCategory, formData, imageFile, fetchCategories]);

  const previewImages = useMemo(() =>
    categories
      .filter(c => typeof c.image === "string" && c.image.trim())
      .map(c => ({ src: c.image, name: c.name })),
    [categories]
  );

  const openPreview = useCallback((index: number) => {
    setActiveIndex(index);
    setPreviewOpen(true);
  }, []);

  return (
    <div className="space-y-6">
      {/* Toolbar */}
      {/* <div className="flex justify-between items-center">
        <Button
          onClick={() => {
            resetForm();
            setEditingCategory(null);
            setIsDialogOpen(true);
          }}
        >
          <Plus className="w-4 h-4 mr-1" />
          Add Category
        </Button>
      </div> */}

      {/* Search + Limit */}
      <div className="flex flex-col gap-4 pt-0 py-1 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex gap-4 pt-0 py-1 flex-row sm:items-center w-full sm:max-w-[500px]">
          <div className="flex items-center gap-4">
            <div className="relative flex-1 max-w-sm">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 h-4 w-4" />
              <Input
                placeholder="Search categories..."
                value={search}
                onChange={(e) => handleSearch(e.target.value)}
                className="pl-10"
              />
              <X
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 h-4 w-4 cursor-pointer"
                onClick={() => handleSearch('')}
              />
            </div>
            <div className="flex items-center gap-2">
              <Label className="text-sm whitespace-nowrap">Show:</Label>
              <select
                value={limit.toString()}
                onChange={(e) => handleLimitChange(e.target.value)}
                className="px-3 py-2.5 rounded-md border border-input text-sm bg-white dark:bg-[#3B3B3B] focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
              >
                <option value="6">6</option>
                <option value="10">10</option>
                <option value="20">20</option>
                <option value="50">50</option>
              </select>
            </div>
    {/* 
            <div className="flex items-center gap-2">
              <Label className="text-sm whitespace-nowrap">Type:</Label>
              <select
                value={eventFilter}
                onChange={(e) => handleEventFilterChange(e.target.value as 'all' | 'true' | 'false')}
                className="px-3 py-2.5 rounded-md border border-input text-sm bg-white dark:bg-[#3B3B3B] focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
              >
                <option value="all">All</option>
                <option value="true">Events</option>
                <option value="false">Categories</option>
              </select>
            </div> */}
          </div>
        </div>
        <div className="flex justify-between items-center">
          <Button
            onClick={() => {
              resetForm();
              setEditingCategory(null);
              setIsDialogOpen(true);
            }}
          >
            <Plus className="w-4 h-4 mr-1" />
            Add Category
          </Button>
        </div>        
      </div>

      {/* Table */}
      <CategoryTable
        categories={categories}
        loading={loading}
        pagination={pagination}
        sortField={sortField}
        sortOrder={sortOrder}
        handleSort={handleSort}
        handleView={handleView}
        handleEdit={handleEdit}
        handleDelete={handleDelete}
        openPreview={openPreview}
      />

      {/* Pagination */}
      {pagination.pages > 1 && (
        <div className="flex items-center justify-between">
          <div className="text-sm text-gray-500">
            Showing {((page - 1) * limit) + 1} to {Math.min(page * limit, pagination.total)} of {pagination.total} results
          </div>
          <div className="flex items-center gap-2">
            <Button variant="default" size="sm" onClick={() => setPage(p => p - 1)} disabled={page === 1}>
              <ChevronLeft className="h-4 w-4" /> Previous
            </Button>
            <span className="text-sm">Page {page} of {pagination.pages}</span>
            <Button variant="default" size="sm" onClick={() => setPage(p => p + 1)} disabled={page === pagination.pages}>
              Next <ChevronRightIcon className="h-4 w-4" />
            </Button>
          </div>
        </div>
      )}

      {/* Dialogs — mounted only when open */}
      {isDialogOpen && (
        <CategoryFormDialog
          open={isDialogOpen}
          onOpenChange={setIsDialogOpen}
          editingCategory={editingCategory}
          formData={formData}
          setFormData={setFormData}
          imageFile={imageFile}
          setImageFile={setImageFile}
          handleSubmit={handleSubmit}
          loading={submitting}
          resetForm={resetForm}
          isValidCategoryName={isValidCategoryName}
          toast={toast}
        />
      )}

      {isViewDialogOpen && (
        <CategoryViewDialog
          open={isViewDialogOpen}
          onOpenChange={setIsViewDialogOpen}
          viewingCategory={viewingCategory}
          handleEdit={handleEdit}
          handleDelete={handleDelete}
        />
      )}

      {previewOpen && (
        <ImagePreviewModal
          images={previewImages}
          activeIndex={activeIndex}
          setActiveIndex={setActiveIndex}
          onClose={() => setPreviewOpen(false)}
        />
      )}
    </div>
  );
}