"use client";

import { useEffect, useState } from "react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";

import { Badge } from "@/components/ui/badge";

import {
  Search,
  ChevronLeft,
  ChevronRight,
  Eye,
  Trash2,
  X,
  ArrowUp,
  ArrowDown,
  ArrowUpDown,
} from "lucide-react";

import { toast } from "sonner";

import { Tooltip } from "@/components/ui/tooltip";

import { useDebounce } from "@/hooks/useDebounce";

import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

interface Appointment {
  _id: string;

  storeId: string;
  storeName: string;

  date: string;
  timeSlot: string;
  slotPeriod: "morning" | "afternoon" | "evening";

  name: string;
  phone: string;
  email: string;

  celebrating: "groom" | "bride" | "event" | "other";
  celebratingOther?: string;
  lookingFor?: string;

  status: "pending" | "confirmed" | "cancelled" | "completed";

  createdAt: string;
  updatedAt: string;
}

interface Store {
  _id: string;
  name: string;
  city?: string;
  address?: string;
}

export default function AppointmentManagement() {
  const [appointments, setAppointments] = useState<Appointment[]>([]);
  const [stores, setStores] = useState<Store[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadingStores, setLoadingStores] = useState(true);

  const [search, setSearch] = useState("");
  const [selectedStore, setSelectedStore] = useState<string>("all");

  const [page, setPage] = useState(1);

  const [limit, setLimit] = useState(10);

  const [sortField, setSortField] = useState<"createdAt" | "name">("createdAt");

  const [sortOrder, setSortOrder] = useState<"asc" | "desc">("desc");

  const [isViewDialogOpen, setIsViewDialogOpen] = useState(false);

  const [viewingAppointment, setViewingAppointment] =
    useState<Appointment | null>(null);

  const [pagination, setPagination] = useState({
    total: 0,
    pages: 0,
    page: 1,
    limit: 10,
  });

  const debouncedSearch = useDebounce(search, 500);
  const debouncedStore = useDebounce(selectedStore, 500);

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

  useEffect(() => {
    fetchAppointments();
  }, [debouncedSearch, debouncedStore, page, limit, sortField, sortOrder]);

  const fetchStores = async () => {
    try {
      setLoadingStores(true);
      const res = await fetch("/api/stores?limit=100");
      const result = await res.json();

      if (result.success) {
        setStores(result.data);
      } else {
        console.error("Failed to fetch stores");
      }
    } catch (error) {
      console.error("Error fetching stores:", error);
    } finally {
      setLoadingStores(false);
    }
  };

  const fetchAppointments = async () => {
    try {
      setLoading(true);

      const params = new URLSearchParams({
        page: page.toString(),
        limit: limit.toString(),
        sort: sortField,
        order: sortOrder,
        ...(debouncedSearch && {
          search: debouncedSearch,
        }),
        ...(debouncedStore &&
          debouncedStore !== "all" && {
            storeId: debouncedStore,
          }),
      });

      const res = await fetch(`/api/appointments?${params}`);

      const result = await res.json();

      if (result.success) {
        setAppointments(result.data);
        setPagination(result.pagination);
      } else {
        toast.error("Failed to fetch appointments");
      }
    } catch {
      toast.error("Error fetching appointments");
    } finally {
      setLoading(false);
    }
  };

  const handleView = (appointment: Appointment) => {
    setViewingAppointment(appointment);
    setIsViewDialogOpen(true);
  };

  const handleDelete = async (id: string) => {
    if (!confirm("Are you sure you want to delete this appointment?")) return;

    try {
      const res = await fetch(`/api/appointments/${id}`, {
        method: "DELETE",
      });

      const result = await res.json();

      if (result.success) {
        toast.success("Appointment deleted successfully");

        if (appointments.length === 1 && page > 1) {
          setPage((prev) => prev - 1);
        } else {
          fetchAppointments();
        }
      } else {
        toast.error(result.error || "Failed to delete appointment");
      }
    } catch {
      toast.error("Error deleting appointment");
    }
  };

  const updateStatus = async (id: string, status: string) => {
    try {
      const res = await fetch(`/api/appointments/${id}`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ status }),
      });

      const result = await res.json();

      if (result.success) {
        toast.success("Status updated");

        setViewingAppointment((prev) =>
          prev
            ? {
                ...prev,
                status: status as Appointment["status"],
              }
            : null,
        );

        fetchAppointments();
      } else {
        toast.error("Failed to update status");
      }
    } catch {
      toast.error("Error updating status");
    }
  };

  const handleSearch = (value: string) => {
    setSearch(value);
    setPage(1);
  };

  const handleStoreFilter = (value: string) => {
    setSelectedStore(value);
    setPage(1);
  };

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

  const handleSort = (field: "createdAt" | "name") => {
    if (sortField === field) {
      setSortOrder(sortOrder === "asc" ? "desc" : "asc");
    } else {
      setSortField(field);
      setSortOrder(field === "name" ? "asc" : "desc");
    }

    setPage(1);
  };

  const formatDate = (dateString: string) => {
    return new Date(dateString).toLocaleString("en-US", {
      year: "numeric",
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  };

  return (
    <div className="rounded-sm">
      {/* VIEW DIALOG */}

      <Dialog open={isViewDialogOpen} onOpenChange={setIsViewDialogOpen}>
        <DialogContent className="max-w-3xl">
          <div className="mx-auto my-2 flex min-h-[calc(100%-0.5rem)] max-w-3xl items-center">
            <div className="relative flex w-full flex-col gap-0 rounded-lg border-0 border-stroke bg-white p-0 shadow-lg dark:bg-[#1f2a37]">
              <DialogHeader className="flex-shrink-0 border-b p-5">
                <DialogTitle>Appointment Details</DialogTitle>

                <X
                  className="h-6 w-6 cursor-pointer p-1 text-white"
                  onClick={() => setIsViewDialogOpen(false)}
                />
              </DialogHeader>

              {viewingAppointment && (
                <div className="max-h-[80vh] overflow-y-auto p-5">
                  {/* TOP INFO */}

                  <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
                    <div className="space-y-1">
                      <Label>Customer Name</Label>
                      <p className="font-medium">{viewingAppointment.name}</p>
                    </div>

                    <div className="space-y-1">
                      <Label>Phone</Label>
                      <p>{viewingAppointment.phone}</p>
                    </div>

                    <div className="space-y-1">
                      <Label>Email</Label>
                      <p>{viewingAppointment.email}</p>
                    </div>

                    <div className="space-y-1">
                      <Label>Store</Label>
                      <p>{viewingAppointment.storeName}</p>
                    </div>

                    <div className="space-y-1">
                      <Label>Date</Label>
                      <p>
                        {new Date(viewingAppointment.date).toLocaleDateString()}
                      </p>
                    </div>

                    <div className="space-y-1">
                      <Label>Time Slot</Label>
                      <p>{viewingAppointment.timeSlot}</p>
                    </div>

                    <div className="space-y-1">
                      <Label>Slot Period</Label>

                      <p className="capitalize">
                        {viewingAppointment.slotPeriod}
                      </p>
                    </div>

                    <div className="space-y-1">
                      <Label>Celebrating</Label>

                      <p className="capitalize">
                        {viewingAppointment.celebrating}
                      </p>
                    </div>

                    {viewingAppointment.celebratingOther && (
                      <div className="space-y-1">
                        <Label>Other Celebration</Label>

                        <p>{viewingAppointment.celebratingOther}</p>
                      </div>
                    )}

                    <div className="space-y-2">
                      <Label>Status</Label>

                      <select
                        value={viewingAppointment.status}
                        onChange={(e) =>
                          updateStatus(viewingAppointment._id, e.target.value)
                        }
                        className="w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800"
                      >
                        <option value="pending">Pending</option>

                        <option value="confirmed">Confirmed</option>

                        <option value="completed">Completed</option>

                        <option value="cancelled">Cancelled</option>
                      </select>
                    </div>
                  </div>

                  {/* LOOKING FOR */}

                  {viewingAppointment.lookingFor && (
                    <div className="mt-6">
                      <Label>Looking For</Label>

                      <div className="mt-2 rounded-md border bg-gray-50 p-4 dark:bg-gray-900">
                        {viewingAppointment.lookingFor}
                      </div>
                    </div>
                  )}

                  {/* DATES */}

                  <div className="mt-6 space-y-2 border-t pt-4 text-sm text-gray-500">
                    <p>
                      Created At: {formatDate(viewingAppointment.createdAt)}
                    </p>

                    <p>
                      Updated At: {formatDate(viewingAppointment.updatedAt)}
                    </p>
                  </div>

                  {/* ACTIONS */}

                  <div className="mt-8 flex justify-end gap-3 border-t pt-5">
                    <Button
                      variant="outline"
                      onClick={() => setIsViewDialogOpen(false)}
                    >
                      Close
                    </Button>

                    <Button
                      variant="destructive"
                      onClick={() => {
                        setIsViewDialogOpen(false);

                        handleDelete(viewingAppointment._id);
                      }}
                    >
                      <Trash2 className="mr-2 h-4 w-4" />
                      Delete
                    </Button>
                  </div>
                </div>
              )}
            </div>
          </div>
        </DialogContent>
      </Dialog>

      {/* SEARCH AND FILTERS */}

      <div className="py-6">
        <div className="flex flex-col gap-4 sm:flex-row">
          {/* Search Input */}
          <div className="relative max-w-sm flex-1">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 transform text-gray-400" />

            <Input
              placeholder="Search appointments..."
              value={search}
              onChange={(e) => handleSearch(e.target.value)}
              className="pl-10"
            />

            {/* {search && ( */}
            <X
              className="absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 cursor-pointer text-gray-400 hover:text-gray-600"
              onClick={() => handleSearch("")}
            />
            {/* )} */}
          </div>

          {/* Store Filter Dropdown */}
          <div className="w-full sm:w-64">
            <select
              value={selectedStore}
              onChange={(e) => handleStoreFilter(e.target.value)}
              className="w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-800"
            >
              <option value="all">All Stores</option>

              {!loadingStores &&
                stores.map((store) => (
                  <option key={store._id} value={store._id}>
                    {store.name}
                  </option>
                ))}
            </select>
          </div>

          {/* Clear Filters Button */}
          {(selectedStore !== "all" || search) && (
            <Button
              variant="outline"
              onClick={() => {
                handleSearch("");
                handleStoreFilter("all");
              }}
              className="shrink-0"
            >
              <X className="mr-2 h-4 w-4" />
              Clear Filters
            </Button>
          )}

          {/* Limit Selector */}
          <div className="ml-auto flex items-center gap-2">
            <Label className="whitespace-nowrap text-sm">Show:</Label>

            <select
              value={limit.toString()}
              onChange={(e) => handleLimitChange(e.target.value)}
              className="border-input rounded-md border px-3 py-2.5 text-sm"
            >
              <option value="10">10</option>
              <option value="20">20</option>
              <option value="50">50</option>
            </select>
          </div>
        </div>
      </div>

      {/* TABLE */}

      <div className="mt-4 rounded-md bg-white dark:bg-gray-900">
        <Table className="border">
          <TableHeader className="dark:bg-gray-800">
            <TableRow>
              <TableHead
                className="cursor-pointer text-center"
                onClick={() => handleSort("createdAt")}
              >
                <div className="flex items-center justify-center gap-2">
                  ID
                  {sortField === "createdAt" ? (
                    sortOrder === "asc" ? (
                      <ArrowUp className="h-4 w-4" />
                    ) : (
                      <ArrowDown className="h-4 w-4" />
                    )
                  ) : (
                    <ArrowUpDown className="h-4 w-4 text-gray-400" />
                  )}
                </div>
              </TableHead>

              <TableHead
                className="cursor-pointer text-center"
                onClick={() => handleSort("name")}
              >
                <div className="flex items-center justify-center gap-2">
                  Customer
                  {sortField === "name" ? (
                    sortOrder === "asc" ? (
                      <ArrowUp className="h-4 w-4" />
                    ) : (
                      <ArrowDown className="h-4 w-4" />
                    )
                  ) : (
                    <ArrowUpDown className="h-4 w-4 text-gray-400" />
                  )}
                </div>
              </TableHead>

              <TableHead className="text-center">Store</TableHead>

              <TableHead className="text-center">Date</TableHead>

              <TableHead className="text-center">Slot</TableHead>

              <TableHead className="text-center">Status</TableHead>

              <TableHead className="text-center">Action</TableHead>
            </TableRow>
          </TableHeader>

          <TableBody>
            {loading ? (
              <TableRow className="bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800">
                <TableCell colSpan={7} className="py-10 text-center">
                  Loading...
                </TableCell>
              </TableRow>
            ) : appointments.length === 0 ? (
              <TableRow className="bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800">
                <TableCell colSpan={7} className="py-10 text-center">
                  No appointments found
                </TableCell>
              </TableRow>
            ) : (
              appointments.map((appointment, index) => (
                <TableRow
                  key={appointment._id}
                  className="bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800"
                >
                  <TableCell className="text-center">
                    {(page - 1) * limit + index + 1}
                  </TableCell>

                  <TableCell className="text-center">
                    <div>
                      <p className="font-medium">{appointment.name}</p>

                      <p className="text-xs text-gray-500">
                        {appointment.phone}
                      </p>
                    </div>
                  </TableCell>

                  <TableCell className="text-center">
                    {appointment.storeName}
                  </TableCell>

                  <TableCell className="text-center">
                    {new Date(appointment.date).toLocaleDateString()}
                  </TableCell>

                  <TableCell className="text-center">
                    <div>
                      <p>{appointment.timeSlot}</p>

                      <p className="text-xs capitalize text-gray-500">
                        {appointment.slotPeriod}
                      </p>
                    </div>
                  </TableCell>

                  <TableCell className="text-center">
                    <Badge
                      variant={
                        appointment.status === "confirmed"
                          ? "default"
                          : appointment.status === "cancelled"
                            ? "destructive"
                            : "outline"
                      }
                    >
                      {appointment?.status &&
                        `${appointment.status.charAt(0).toUpperCase()}${appointment.status.slice(1)}`}
                    </Badge>
                  </TableCell>

                  <TableCell className="text-center">
                    <div className="flex justify-center gap-2">
                      <Tooltip text="View">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => handleView(appointment)}
                        >
                          <Eye className="h-4 w-4" />
                        </Button>
                      </Tooltip>

                      <Tooltip text="Delete">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => handleDelete(appointment._id)}
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </Tooltip>
                    </div>
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>

        {/* PAGINATION */}

        {pagination.pages > 1 && (
          <div className="mt-4 flex items-center justify-between p-4">
            <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(page - 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(page + 1)}
                disabled={page === pagination.pages}
              >
                Next
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
