"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}/status`,
        {
          method: "PATCH",
          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="flex items-center max-w-3xl min-h-[calc(100%-0.5rem)] my-2 mx-auto">
            <div className="relative flex flex-col w-full rounded-lg gap-0 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 p-1 text-white cursor-pointer"
                  onClick={() =>
                    setIsViewDialogOpen(false)
                  }
                />
              </DialogHeader>

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

                  {/* TOP INFO */}

                  <div className="grid grid-cols-1 md:grid-cols-2 gap-5">

                    <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 border border-gray-300 rounded-md px-3 py-2 bg-white 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 border rounded-md p-4 bg-gray-50 dark:bg-gray-900">
                        {
                          viewingAppointment.lookingFor
                        }
                      </div>
                    </div>
                  )}

                  {/* DATES */}

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

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

                  {/* ACTIONS */}

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

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

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

      {/* SEARCH AND FILTERS */}

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

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

            {/* {search && ( */}
              <X
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 h-4 w-4 cursor-pointer 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 border border-gray-300 rounded-md px-3 dark:bg-gray-800 py-2 bg-white text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
  <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="h-4 w-4 mr-2" />
              Clear Filters
            </Button>
          )}

          {/* Limit Selector */}
          <div className="flex items-center gap-2 ml-auto">
            <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"
            >
              <option value="10">10</option>
              <option value="20">20</option>
              <option value="50">50</option>
            </select>
          </div>
        </div>
      </div>

      {/* TABLE */}

      <div className="rounded-md bg-white dark:bg-gray-900 mt-4">

        <Table className="border">
          <TableHeader className="bg-gray-100 dark:bg-gray-800">

            <TableRow>

              <TableHead
                className="text-center cursor-pointer"
                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="text-center cursor-pointer"
                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 dark:bg-gray-900 hover:bg-gray-50 dark:hover:bg-gray-800'
              >
                <TableCell
                  colSpan={7}
                  className="text-center py-10"
                >
                  Loading...
                </TableCell>
              </TableRow>
            ) : appointments.length === 0 ? (
              <TableRow className='bg-white dark:bg-gray-900 hover:bg-gray-50 dark:hover:bg-gray-800'>
                <TableCell
                  colSpan={7}
                  className="text-center py-10"
                >
                  No appointments found
                </TableCell>
              </TableRow>
            ) : (
              appointments.map(
                (appointment, index) => (
                  <TableRow
                    key={appointment._id}
                    className='bg-white dark:bg-gray-900 hover:bg-gray-50 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 text-gray-500 capitalize">
                          {
                            appointment.slotPeriod
                          }
                        </p>
                      </div>
                    </TableCell>

                    <TableCell className="text-center">
                      <Badge
                        variant={
                          appointment.status ===
                          "confirmed"
                            ? "default"
                            : appointment.status ===
                              "cancelled"
                            ? "destructive"
                            : "secondary"
                        }
                      >
                        {
                          appointment.status
                        }
                      </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="flex items-center justify-between mt-4 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="outline"
                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="outline"
                size="sm"
                onClick={() =>
                  setPage(page + 1)
                }
                disabled={
                  page === pagination.pages
                }
              >
                Next
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}