"use client";

import React, { useState, useEffect } from "react";
import { useParams, useRouter } from "next/navigation";
import { Users, Coffee, Sun, Moon, ChevronDown, Plus, X } from "lucide-react";
import apis from "@/utils/apis";
import DashboardLayout from "@/components/layout/DashboardLayout";
import {
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
} from "@/components/ui/accordion";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import PaymentModal from "@/components/payment/page";
import { useGlobalContext } from "@/context/Provider";

interface SlotData {
  _id: string;
  restaurant_id: string;
  start: string;
  end: string;
  maximum_capacity_slot: number;
  status: "NotBooked" | "Booked";
  __v: number;
  createdAt: string;
  updatedAt: string;
}

interface CategorizedSlots {
  breakfast: SlotData[];
  lunch: SlotData[];
  dinner: SlotData[];
}

type SlotType = keyof CategorizedSlots;

interface SpecialRequest {
  id: string;
  text: string;
}

interface PaymentGatewayConfig {
  paymentGateway: "stripe" | "razorpay" | "cashfree";
  stripe?: {
    key: string;
    secret: string;
    webhook: string;
  };
  razorpay?: {
    key: string;
    secret: string;
    bank_account: string;
  };
  cashfree?: {
    client_id: string;
    client_secret: string;
    webhook_secret: string;
  };
}

const SlotsPage = () => {
  const params = useParams();
  const router = useRouter();
  const restaurantId = params.restaurantId as string;
  const { Toast } = useGlobalContext();

  const [selectedDate, setSelectedDate] = useState(0);
  const [guestCount, setGuestCount] = useState(2);
  const [selectedSlotData, setSelectedSlotData] = useState<SlotData | null>(null);
  const [restaurant, setRestaurant] = useState<any>(null);
  const [availableSlots, setAvailableSlots] = useState<CategorizedSlots>({
    breakfast: [],
    lunch: [],
    dinner: [],
  });
  const [loading, setLoading] = useState(true);

  const [specialRequests, setSpecialRequests] = useState<SpecialRequest[]>([]);
  const [occasionType, setOccasionType] = useState("");
  const [modalOpen, setModalOpen] = useState(false);
  const [modalType, setModalType] = useState<"special" | "occasion" | null>(null);
  const [tempSpecialRequest, setTempSpecialRequest] = useState("");
  const [tempOccasionType, setTempOccasionType] = useState("");

  // Payment states
  const [paymentModalOpen, setPaymentModalOpen] = useState(false);
  const [paymentData, setPaymentData] = useState<any>(null);
  const [paymentConfig, setPaymentConfig] = useState<PaymentGatewayConfig | null>(null);

  const generateDateOptions = () => {
    const dates: Date[] = [];
    const today = new Date();
    for (let i = 0; i < 7; i++) {
      const date = new Date(today);
      date.setDate(today.getDate() + i);
      dates.push(date);
    }
    return dates;
  };
  const dateOptions = generateDateOptions();

  const formatDateForButton = (date: Date) => {
    const day = date.getDate().toString();
    const month = date.toLocaleDateString("en-US", { month: "short" });
    const weekday = date.toLocaleDateString("en-US", { weekday: "short" });
    return { day, month, weekday };
  };

  const formatTimeWithAMPM = (isoString: string) => {
    const date = new Date(isoString);
    return date.toLocaleTimeString("en-US", {
      hour: "numeric",
      minute: "2-digit",
      hour12: true,
    });
  };

  // Check if a slot time has passed
  const isSlotInPast = (slotStartTime: string, dateIndex: number): boolean => {
    const slotDate = new Date(slotStartTime);
    const now = new Date();

    // If it's today (dateIndex === 0), check if the time has passed
    if (dateIndex === 0) {
      return slotDate <= now;
    }

    // Future dates are never in the past
    return false;
  };

  // Filter out past slots
  const filterAvailableSlots = (slots: SlotData[], dateIndex: number): SlotData[] => {
    return slots.filter(slot => !isSlotInPast(slot.start, dateIndex));
  };

  const categorizeSlots = (slots: SlotData[], dateIndex: number): CategorizedSlots => {
    const categorized: CategorizedSlots = { breakfast: [], lunch: [], dinner: [] };

    // Filter out past slots first
    const availableSlots = filterAvailableSlots(slots, dateIndex);

    availableSlots.forEach((slot) => {
      const hour = new Date(slot.start).getHours();
      if (hour >= 6 && hour < 12) categorized.breakfast.push(slot);
      else if (hour >= 12 && hour < 17) categorized.lunch.push(slot);
      else if (hour >= 17 && hour < 23) categorized.dinner.push(slot);
    });

    return categorized;
  };

  const openModal = (type: "special" | "occasion") => {
    setModalType(type);
    if (type === "special") setTempSpecialRequest("");
    else setTempOccasionType(occasionType);
    setModalOpen(true);
  };

  const closeModal = () => {
    setModalOpen(false);
    setModalType(null);
    setTempSpecialRequest("");
    setTempOccasionType("");
  };

  const saveSpecialRequest = () => {
    if (tempSpecialRequest.trim()) {
      const newRequest: SpecialRequest = {
        id: Date.now().toString(),
        text: tempSpecialRequest.trim(),
      };
      setSpecialRequests([...specialRequests, newRequest]);
    }
    closeModal();
  };

  const saveOccasionType = () => {
    setOccasionType(tempOccasionType.trim());
    closeModal();
  };

  const removeSpecialRequest = (id: string) => {
    setSpecialRequests(specialRequests.filter((req) => req.id !== id));
  };

  const loadRazorpayScript = () => {
    return new Promise((resolve) => {
      const script = document.createElement("script");
      script.src = "https://checkout.razorpay.com/v1/checkout.js";
      script.onload = () => resolve(true);
      script.onerror = () => resolve(false);
      document.body.appendChild(script);
    });
  };

  const loadCashfreeScript = () => {
    return new Promise((resolve) => {
      if ((window as any).Cashfree) {
        resolve(true);
        return;
      }
      const script = document.createElement("script");
      script.src = "https://sdk.cashfree.com/js/v3/cashfree.js";
      script.onload = () => resolve(true);
      script.onerror = () => resolve(false);
      document.body.appendChild(script);
    });
  };

  // Fetch payment configuration
  const fetchPaymentConfiguration = async () => {
    try {
      const query = new URLSearchParams({ type: "payment" }).toString();
      const res = await apis.ConfigurationType.listing(query);

      if (res?.data) {
        setPaymentConfig(res.data);
      }
    } catch (error) {
      Toast.error(error);
    }
  };

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

  useEffect(() => {
    async function fetchData() {
      try {
        setLoading(true);
        const restaurantRes = await apis.restaurant.detail(restaurantId, "");
        setRestaurant(restaurantRes?.data);

        const date = dateOptions[selectedDate].toISOString();
        const query = new URLSearchParams({ date, page: "1", limit: "100" }).toString();
        const slotsRes = await apis.Slots.getRestaurantSlots(restaurantId, query);

        // Pass selectedDate to categorizeSlots to filter past times
        setAvailableSlots(categorizeSlots(slotsRes?.data || [], selectedDate));
      } catch (error) {
        console.error("Failed to fetch data", error);
      } finally {
        setLoading(false);
      }
    }

    if (restaurantId) fetchData();
  }, [restaurantId, selectedDate]);

  useEffect(() => {
    if (selectedSlotData && guestCount > selectedSlotData.maximum_capacity_slot) {
      setGuestCount(selectedSlotData.maximum_capacity_slot);
    }
  }, [selectedSlotData, guestCount]);

  // Handle booking & payment
  const handleProceed = async () => {
    if (!selectedSlotData) return;

    // Validate slot is not in the past
    if (isSlotInPast(selectedSlotData.start, selectedDate)) {
      Toast.error("Cannot book a slot in the past. Please select a future time.");
      setSelectedSlotData(null); // Clear the selection
      return;
    }

    if (!paymentConfig) {
      Toast.error("Payment configuration not loaded");
      return;
    }

    try {
      const payload = {
        slot_id: selectedSlotData._id,
        special_request: specialRequests?.map((req) => req.text).join(", "),
        occasion_type: occasionType,
        no_of_guest: guestCount,
        // callback_url: window.location.origin + "/payment-callback"
      };

      const response = await apis.Slots.bookSlot(payload);

      if (response) {
        setPaymentData(response);

        if (response?.paytab?.redirect_url) {
          window.location.href = response.paytab.redirect_url;
          return;
        }

        const bookingDate = dateOptions[selectedDate].toLocaleDateString("en-US", {
          day: "numeric",
          month: "long",
          year: "numeric",
        });
        const bookingTime = formatTimeWithAMPM(selectedSlotData.start);
        const restaurantName = restaurant?.name || "Restaurant";
        const bookingAmount = response.booking_amount || response.amount || 0;
        if (bookingAmount <= 0) {
          router.push(
            `/booking-confirmation?restaurantName=${encodeURIComponent(
              restaurantName
            )}&date=${encodeURIComponent(bookingDate)}&time=${encodeURIComponent(bookingTime)}`
          );
          return;
        }
        if (paymentConfig.paymentGateway === "cashfree" && response.cashfree) {
          const scriptLoaded = await loadCashfreeScript();
          if (!scriptLoaded) {
            Toast.error("Cashfree SDK failed to load");
            return;
          }

          if (!(window as any).Cashfree) {
            Toast.error("Cashfree SDK not available");
            return;
          }

          const isSandbox = !paymentConfig.cashfree?.client_id || paymentConfig.cashfree.client_id.startsWith("TEST");
          const cashfree = (window as any).Cashfree({
            mode: isSandbox ? "sandbox" : "production",
          });

          const checkoutOptions = {
            paymentSessionId: response.cashfree.payment_session_id,
            redirectTarget: "_self",
          };

          cashfree.checkout(checkoutOptions);
          return;
        }

        if (paymentConfig.paymentGateway === "razorpay" && response.razorpay) {
          const scriptLoaded = await loadRazorpayScript();
          if (!scriptLoaded) {
            Toast.error("Razorpay SDK failed to load");
            return;
          }

          if (!paymentConfig.razorpay?.key) {
            Toast.error("Razorpay key not configured");
            return;
          }

          const options = {
            key: paymentConfig.razorpay.key,
            amount: response.razorpay.amount,
            currency: response.razorpay.currency,
            name: restaurantName,
            description: "Booking Payment",
            order_id: response.razorpay.id,
            handler: function (res: any) {
              Toast.success("Payment successful");
              router.push(
                `/booking-confirmation?restaurantName=${encodeURIComponent(
                  restaurantName
                )}&date=${encodeURIComponent(bookingDate)}&time=${encodeURIComponent(bookingTime)}`
              );
            },
            prefill: { name: "", email: "", contact: "" },
            theme: { color: "#000000" },
          };

          const rzp = new (window as any).Razorpay(options);
          rzp.open();

        } else if (paymentConfig.paymentGateway === "stripe" && response.client_secret) {
          sessionStorage.setItem("clientSecret", response.client_secret);
          setPaymentModalOpen(true);
        }
      }
    } catch (error) {
      console.error("Error booking slot", error);
      Toast.error("Failed to book slot");
    }
  };

  if (loading)
    return (
      <DashboardLayout>
        <p className="text-center py-20">Loading booking details...</p>
      </DashboardLayout>
    );
  if (!restaurant)
    return (
      <DashboardLayout>
        <p className="text-center py-20">Vendor/Store not found.</p>
      </DashboardLayout>
    );

  return (
    <>
      <div className="w-full max-w-2xl mx-auto bg-white min-h-screen flex flex-col">
        {/* Date Selection */}
        <section className="p-4 border-b">
          <h3 className="font-medium text-gray-900 mb-4 text-base">When are you visiting?</h3>
          <div className="flex justify-between gap-3">
            {dateOptions.map((date, idx) => {
              const { day, month, weekday } = formatDateForButton(date);
              const selected = selectedDate === idx;
              return (
                <button
                  key={idx}
                  onClick={() => {
                    setSelectedDate(idx);
                    setSelectedSlotData(null);
                  }}
                  className={`flex flex-col items-center px-3 py-2 rounded-lg border min-w-[60px] transition-colors ${selected
                    ? "bg-primary text-white border-primary"
                    : "bg-white border-gray-200 text-gray-700 hover:border-gray-300"
                    }`}
                >
                  <div className="text-xs font-medium">{weekday}</div>
                  <div className="text-sm font-semibold">{day}</div>
                  <div className="text-xs">{month}</div>
                </button>
              );
            })}
          </div>
        </section>

        {/* Slot Type Accordion */}
        <section className="p-4 border-b">
          <h3 className="font-medium text-gray-900 mb-4 text-base">Select the time of the day</h3>
          <Accordion type="single" collapsible className="space-y-2">
            {(["breakfast", "lunch", "dinner"] as SlotType[]).map((type) => {
              const slots = availableSlots[type];
              const getIcon = (mealType: string) => {
                switch (mealType) {
                  case "breakfast":
                    return <Coffee size={18} />;
                  case "lunch":
                    return <Sun size={18} />;
                  case "dinner":
                    return <Moon size={18} />;
                  default:
                    return null;
                }
              };

              return (
                <AccordionItem key={type} value={type}>
                  <AccordionTrigger className="flex items-center justify-between bg-gray-100 px-4 py-2 rounded-md">
                    <div className="flex items-center gap-2">
                      {getIcon(type)}
                      <span className="font-medium capitalize">{type}</span>
                    </div>
                    <ChevronDown
                      size={18}
                      className="transition-transform duration-200 data-[state=open]:rotate-180"
                    />
                  </AccordionTrigger>
                  <AccordionContent className="pt-2 pb-4">
                    {slots.length > 0 ? (
                      <div className="grid grid-cols-3 gap-3">
                        {slots.map((slot) => {
                          const isAvailable = slot.maximum_capacity_slot > 0;
                          const isSelected = selectedSlotData?._id === slot._id;

                          return (
                            <button
                              key={slot._id}
                              onClick={() => isAvailable && setSelectedSlotData(slot)}
                              disabled={!isAvailable}
                              className={`py-3 px-3 rounded-lg text-sm font-medium border transition-colors flex flex-col items-center ${isSelected
                                ? "bg-primary text-white border-primary"
                                : isAvailable
                                  ? "bg-white border-gray-200 text-gray-700 hover:border-gray-300"
                                  : "bg-gray-100 border-gray-200 text-gray-400 cursor-not-allowed"
                                }`}
                            >
                              <span className="font-medium">{formatTimeWithAMPM(slot.start)}</span>
                              <span className="text-xs opacity-75 mt-1">{slot.maximum_capacity_slot} seats</span>
                            </button>
                          );
                        })}
                      </div>
                    ) : (
                      <div className="text-center py-4 text-gray-500 text-sm">
                        No {type} slots available
                      </div>
                    )}
                  </AccordionContent>
                </AccordionItem>
              );
            })}
          </Accordion>
        </section>

        {/* Guests */}
        <section className="p-4 border-b flex flex-col gap-2">
          <div className="flex items-center gap-2 mb-2">
            <Users size={18} className="text-gray-600" />
            <h3 className="font-medium text-gray-900 text-base">Guests</h3>
          </div>
          <div className="flex flex-col gap-2">
            <span className="text-gray-700 text-sm">No. of guest(s)</span>
            <div className="flex flex-wrap gap-2">
              {selectedSlotData ? (
                Array.from({ length: selectedSlotData.maximum_capacity_slot }, (_, idx) => idx + 1).map(
                  (num) => (
                    <button
                      key={num}
                      onClick={() => setGuestCount(num)}
                      className={`w-10 h-10 flex items-center justify-center rounded-md border text-sm font-medium transition-colors ${guestCount === num
                        ? "bg-brand-100 border-primary text-primary"
                        : "bg-white border-gray-200 text-gray-700 hover:border-primary"
                        }`}
                    >
                      {num}
                    </button>
                  )
                )
              ) : (
                <p className="text-sm text-gray-500 italic">Select a slot first</p>
              )}
            </div>
          </div>
        </section>

        {/* Special Requests & Occasion */}
        <section className="p-4 border-b">
          <div className="flex flex-col gap-4">
            <div className="flex items-center justify-between">
              <span className="text-gray-700 text-sm">Add special requests</span>
              <Button
                variant="outline"
                size="sm"
                className="text-primary"
                onClick={() => openModal("special")}
              >
                <Plus size={14} /> Add
              </Button>
            </div>
            {specialRequests.length > 0 && (
              <div className="flex flex-wrap gap-2">
                {specialRequests.map((req) => (
                  <div
                    key={req.id}
                    className="flex items-center gap-2 bg-brand-100 text-primary px-3 py-1 rounded-full text-sm"
                  >
                    <span>{req.text}</span>
                    <button onClick={() => removeSpecialRequest(req.id)}>
                      <X size={14} />
                    </button>
                  </div>
                ))}
              </div>
            )}

            <div className="flex items-center justify-between">
              <span className="text-gray-700 text-sm">Add Occasion type</span>
              <Button
                variant="outline"
                size="sm"
                className="text-primary"
                onClick={() => openModal("occasion")}
              >
                <Plus size={14} /> Add
              </Button>
            </div>
            {occasionType && (
              <div className="inline-flex items-center gap-2 bg-brand-100 text-primary px-3 py-1 rounded-full text-sm">
                <span>{occasionType}</span>
                <button onClick={() => setOccasionType("")}>
                  <X size={14} />
                </button>
              </div>
            )}
          </div>
        </section>

        {/* Proceed Button */}
        <div className="sticky bottom-0 bg-white border-t p-4">
          <Button
            className="w-full bg-primary hover:bg-primary text-white"
            disabled={!selectedSlotData}
            onClick={handleProceed}
          >
            Proceed
          </Button>
        </div>
      </div>

      {/* ShadCN Dialog */}
      <Dialog open={modalOpen} onOpenChange={setModalOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>{modalType === "special" ? "Add Special Request" : "Add Occasion Type"}</DialogTitle>
          </DialogHeader>

          {modalType === "special" ? (
            <textarea
              value={tempSpecialRequest}
              onChange={(e) => setTempSpecialRequest(e.target.value)}
              placeholder="Enter your special request..."
              className="w-full p-3 border border-gray-300 rounded-lg resize-none focus:border-primary"
              rows={3}
            />
          ) : (
            <input
              type="text"
              value={tempOccasionType}
              onChange={(e) => setTempOccasionType(e.target.value)}
              placeholder="e.g., Birthday, Anniversary..."
              className="w-full p-3 border border-primary rounded-lg focus:border-primary"
            />
          )}

          <DialogFooter className="flex gap-3 mt-4">
            <Button className="flex-1 bg-red-500 hover:bg-red-600 text-white" onClick={closeModal}>
              Cancel
            </Button>
            <Button
              className="flex-1 bg-primary hover:bg-primary text-white"
              disabled={modalType === "special" ? !tempSpecialRequest.trim() : !tempOccasionType.trim()}
              onClick={modalType === "special" ? saveSpecialRequest : saveOccasionType}
            >
              Save
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {paymentConfig?.paymentGateway === "stripe" && paymentData && (
        <PaymentModal
          open={paymentModalOpen}
          setOpen={setPaymentModalOpen}
          price={paymentData.booking_amount || paymentData.amount}
          clientSecret={paymentData.client_secret}
          stripePublishableKey={paymentConfig.stripe?.key}
          onSuccess={() => {
            const bookingDate = dateOptions[selectedDate].toLocaleDateString("en-US", {
              day: "numeric",
              month: "long",
              year: "numeric",
            });
            const bookingTime = selectedSlotData ? formatTimeWithAMPM(selectedSlotData.start) : "";
            const restaurantName = restaurant?.name || "Restaurant";

            Toast.success("Payment successful");
            router.push(
              `/booking-confirmation?restaurantName=${encodeURIComponent(
                restaurantName
              )}&date=${encodeURIComponent(bookingDate)}&time=${encodeURIComponent(bookingTime)}`
            );
          }}
        />
      )}
    </>
  );
};

export default function SlotsPageWrapper() {
  return (
    <DashboardLayout>
      <SlotsPage />
    </DashboardLayout>
  );
}