"use client";

import React, { useState, useEffect, useRef, useMemo } from "react";
import { ChevronLeft, ChevronRight, X, Calendar as CalendarIcon } from "lucide-react";
import { cnMerge } from "@/lib/utils";

export interface DatePickerProps {
  mode: "single" | "range";
  // Props for single mode
  selectedDate?: Date;
  onChangeSingle?: (date?: Date) => void;
  // Props for range mode
  startDate?: Date;
  endDate?: Date;
  onChangeRange?: (start?: Date, end?: Date) => void;
  
  minDate?: Date;
  placeholder?: string;
  label?: string;
  isDark?: boolean;

  onClear?: () => void;
}

export function DatePicker({
  mode,
  selectedDate,
  onChangeSingle,
  startDate,
  endDate,
  onChangeRange,
  minDate = new Date(),
  placeholder = "Select Date",
  label,
  isDark = false,
  onClear,
}: DatePickerProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [currentMonth, setCurrentMonth] = useState(() => {
    const initial = mode === "range" ? (startDate || new Date()) : (selectedDate || new Date());
    return new Date(initial.getFullYear(), initial.getMonth(), 1);
  });
  
  const [hoveredDate, setHoveredDate] = useState<Date | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  
  // Set minDate time to midnight to avoid timezone date comparison issues
  const startOfMinDate = useMemo(() => {
    const d = new Date(minDate);
    d.setHours(0, 0, 0, 0);
    return d;
  }, [minDate]);

  // Click outside listener for desktop popover
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }
    if (isOpen) {
      document.addEventListener("mousedown", handleClickOutside);
    }
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, [isOpen]);

  // Sync scroll lock on mobile when open
  useEffect(() => {
    if (isOpen) {
      const isMobile = window.innerWidth < 1024;
      if (isMobile) {
        document.body.style.overflow = "hidden";
      }
    } else {
      document.body.style.overflow = "";
    }
    return () => {
      document.body.style.overflow = "";
    };
  }, [isOpen]);

  // Calendar math
  const daysInMonth = useMemo(() => {
    const year = currentMonth.getFullYear();
    const month = currentMonth.getMonth();
    
    // First day of current month index (0: Sun, 1: Mon, etc.)
    const firstDayIndex = new Date(year, month, 1).getDay();
    
    // Number of days in current month
    const totalDays = new Date(year, month + 1, 0).getDate();
    
    // Number of days in previous month
    const prevTotalDays = new Date(year, month, 0).getDate();
    
    const days: { date: Date; isCurrentMonth: boolean; isDisabled: boolean }[] = [];
    
    // Previous month's trailing days
    for (let i = firstDayIndex - 1; i >= 0; i--) {
      const d = new Date(year, month - 1, prevTotalDays - i);
      days.push({
        date: d,
        isCurrentMonth: false,
        isDisabled: d < startOfMinDate,
      });
    }
    
    // Current month's days
    for (let i = 1; i <= totalDays; i++) {
      const d = new Date(year, month, i);
      days.push({
        date: d,
        isCurrentMonth: true,
        isDisabled: d < startOfMinDate,
      });
    }
    
    // Next month's leading days to fill up grid (multiple of 7, usually 35 or 42 cells)
    const remainingCells = (7 - (days.length % 7)) % 7;
    for (let i = 1; i <= remainingCells; i++) {
      const d = new Date(year, month + 1, i);
      days.push({
        date: d,
        isCurrentMonth: false,
        isDisabled: d < startOfMinDate,
      });
    }
    
    return days;
  }, [currentMonth, startOfMinDate]);

  const monthNames = [
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  ];
  
  const weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

  const formatDisplayDate = (d?: Date) => {
    if (!d) return "";
    const day = d.getDate().toString().padStart(2, "0");
    const month = monthNames[d.getMonth()].slice(0, 3);
    const year = d.getFullYear();
    return `${day} ${month} ${year}`;
  };

  const handlePrevMonth = () => {
    setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1));
  };

  const handleNextMonth = () => {
    setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1));
  };

  const handleDateClick = (date: Date) => {
  const targetDate = new Date(
    date.getFullYear(),
    date.getMonth(),
    date.getDate()
  );

  if (targetDate < startOfMinDate) {
    return;
  }

  if (mode === "single") {
    onChangeSingle?.(targetDate);
    setIsOpen(false);
    return;
  }

  if (!startDate || endDate) {
    onChangeRange?.(targetDate, undefined);
    return;
  }

  if (targetDate < startDate) {
    onChangeRange?.(targetDate, undefined);
    return;
  }

  onChangeRange?.(startDate, targetDate);
  setIsOpen(false);
};

    const isSameDay = (d1: Date, d2: Date) => {
    return (
      d1.getFullYear() === d2.getFullYear() &&
      d1.getMonth() === d2.getMonth() &&
      d1.getDate() === d2.getDate()
    );
  };

  const isSelected = (date: Date) => {
    if (mode === "single") {
      return selectedDate ? isSameDay(selectedDate, date) : false;
    }
    return (
      (startDate && isSameDay(startDate, date)) ||
      (endDate && isSameDay(endDate, date))
    );
  };



  const isInRange = (date: Date) => {
    if (mode !== "range" || !startDate) return false;
    
    if (endDate) {
      return date > startDate && date < endDate;
    }
    
    if (hoveredDate) {
      return date > startDate && date < hoveredDate;
    }
    
    return false;
  };

  // Helper to determine active range boundary styles
  const isRangeStart = (date: Date) => {
    return mode === "range" && startDate && isSameDay(startDate, date);
  };

  const isRangeEnd = (date: Date) => {
    return mode === "range" && endDate && isSameDay(endDate, date);
  };

  // Generate input value representation
  const inputValue = useMemo(() => {
    if (mode === "single") {
      return selectedDate ? formatDisplayDate(selectedDate) : "";
    } else {
      if (startDate && endDate) {
        return `${formatDisplayDate(startDate)} — ${formatDisplayDate(endDate)}`;
      } else if (startDate) {
        return `${formatDisplayDate(startDate)} — Check Out`;
      }
      return "";
    }
  }, [mode, selectedDate, startDate, endDate]);

  return (
    <div className="relative w-full" ref={containerRef}>
      {label && (
        <label className="font-sans text-[11px] font-normal uppercase tracking-widest-x text-gold-deep block mb-2">
          {label}
        </label>
      )}
      
      {/* Trigger Button */}
      <button
        type="button"
        onClick={() => setIsOpen(!isOpen)}
        className={cnMerge(
          "w-full text-left bg-transparent border-b py-2.5 font-sans text-xs focus:outline-none flex items-center justify-between cursor-pointer group transition-all",
          isDark 
            ? "border-ivory/20 text-ivory focus:border-gold hover:border-ivory/40" 
            : "border-espresso/20 text-espresso focus:border-gold-deep hover:border-espresso/40"
        )}
      >
        <span
  className={cnMerge(
    "transition-colors",
    !inputValue && "opacity-40",
    inputValue
      ? isDark
        ? "text-ivory"
        : "text-espresso"
      : isDark
        ? "text-ivory/40"
        : "text-espresso/40"
  )}
>
  {inputValue || placeholder}
</span>

<div className="flex items-center gap-2">
  {inputValue && onClear && (
    <span
      role="button"
      tabIndex={0}
      onClick={(e) => {
        e.stopPropagation();
        onClear();
      }}
      onKeyDown={(e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          e.stopPropagation();
          onClear();
        }
      }}
      className={cnMerge(
        "text-[10px] uppercase tracking-wider transition-colors cursor-pointer",
        isDark
          ? "text-ivory/50 hover:text-gold"
          : "text-espresso/50 hover:text-gold-deep"
      )}
    >
      Clear
    </span>
  )}
        <CalendarIcon className={cnMerge("h-3.5 w-3.5 transition-colors", isDark ? "text-ivory/60 group-hover:text-gold" : "text-espresso/60 group-hover:text-gold-deep")} />
        </div>
      </button>

      {/* Calendar Overlay (Desktop: Popover, Mobile: Slide-up Drawer) */}
      {isOpen && (
        <>
          {/* Backdrop Overlay for mobile */}
          <div 
            className="fixed inset-0 z-[1100] bg-midnight/50 backdrop-blur-sm lg:hidden animate-fade-in"
            onClick={() => setIsOpen(false)}
          />
          
          <div
            className={cnMerge(
              // Common
              "z-[1200] border font-sans select-none flex flex-col transition-all duration-300",
              // Mobile styles (Bottom sheet / Drawer)
              "fixed bottom-0 inset-x-0 rounded-t-2xl p-6 bg-ivory border-t border-espresso/10 max-h-[85vh] overflow-y-auto lg:rounded-none lg:p-5 lg:shadow-xl",
              // Desktop styles (Popover below input)
              "lg:absolute lg:top-full lg:left-0 lg:bottom-auto lg:inset-x-auto lg:w-[320px] lg:mt-2 lg:bg-ivory lg:border-espresso/10 lg:animate-slide-down",
              // Dark variant styles
              isDark ? "bg-midnight border-ivory/10 text-ivory lg:bg-midnight" : "bg-ivory border-espresso/10 text-espresso lg:bg-ivory"
            )}
          >
            {/* Mobile Title & Close Header */}
            <div className="flex items-center justify-between pb-4 mb-4 border-b border-espresso/10 lg:hidden">
              <span className="font-serif italic text-lg text-gold-deep">
                {mode === "range" ? "Select Stay Dates" : "Select Date"}
              </span>
              <button 
                type="button"
                onClick={() => setIsOpen(false)}
                className="p-1 rounded-full hover:bg-espresso/5 text-espresso/60"
              >
                <X className="h-5 w-5" />
              </button>
            </div>

            {/* Calendar Header: Month Navigation */}
            <div className="flex items-center justify-between mb-4">
              <button
                type="button"
                onClick={handlePrevMonth}
                className="p-2 cursor-pointer hover:bg-espresso/5 rounded-none transition-colors duration-200"
              >
                <ChevronLeft className="h-4 w-4 text-gold-deep" />
              </button>
              
              <span
  className={cnMerge(
    "font-serif italic text-base md:text-lg tracking-wide",
    isDark ? "text-ivory" : "text-espresso"
  )}
>
                {monthNames[currentMonth.getMonth()]} {currentMonth.getFullYear()}
              </span>
              
              <button
                type="button"
                onClick={handleNextMonth}
                className="p-2 cursor-pointer hover:bg-espresso/5 rounded-none transition-colors duration-200"
              >
                <ChevronRight className="h-4 w-4 text-gold-deep" />
              </button>
            </div>

            {/* Weekdays Labels */}
            <div className="grid grid-cols-7 gap-1 text-center mb-2">
              {weekDays.map((day) => (
                <span 
                  key={day} 
                  className={cnMerge(
  "text-[10px] font-medium uppercase tracking-widest py-1",
  isDark ? "text-ivory/70" : "text-espresso/40"
)}
                >
                  {day}
                </span>
              ))}
            </div>

            {/* Days Grid */}
            <div className="grid grid-cols-7 gap-1 text-center">
              {daysInMonth.map(({ date, isCurrentMonth, isDisabled }, index) => {
                const selected = isSelected(date);
                const rangeStart = isRangeStart(date);
                const rangeEnd = isRangeEnd(date);
                const inRange = isInRange(date);
                
                return (
                  <button
                    key={index}
                    type="button"
                    disabled={isDisabled}
                    onClick={() => handleDateClick(date)}
                    onMouseEnter={() => mode === "range" && !endDate && setHoveredDate(date)}
                    onMouseLeave={() => mode === "range" && setHoveredDate(null)}
                    className={cnMerge(
                      // Base Day Cell (spacious tap targets: min-h-10 or 44px on mobile)
                      "h-10 w-full text-xs font-light flex items-center justify-center relative transition-all duration-150 cursor-pointer",
                      // Month boundary styling
                     !isCurrentMonth &&
  (isDark ? "text-ivory/20" : "text-espresso/20"),

isDisabled &&
  (isDark
    ? "text-ivory/20 line-through cursor-not-allowed pointer-events-none"
    : "text-espresso/20 line-through cursor-not-allowed pointer-events-none"),   
                      // Highlight ranges
                      inRange && !selected && "bg-gold/10 text-espresso font-normal",
                      
                      // Selection styles
                      selected && "bg-gold text-white font-medium scale-105 shadow-md shadow-gold/20 z-10",
                      rangeStart && "bg-gold text-white font-medium rounded-l-none",
                      rangeEnd && "bg-gold text-white font-medium rounded-r-none",
                      
                      // Hover states (non-disabled)
                      !selected && !inRange && !isDisabled && "hover:bg-cream hover:text-espresso"
                    )}
                  >
                    {/* Today Indicator */}
                    {isSameDay(date, new Date()) && !selected && (
                      <span className="absolute bottom-1.5 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-gold-deep" />
                    )}
                    
                    <span>{date.getDate()}</span>
                  </button>
                );
              })}
            </div>

            {/* Mobile Confirmation Action Strip */}
            {mode === "range" && startDate && (
              <div className="mt-5 pt-4 border-t border-espresso/10 lg:hidden flex flex-col gap-2">
                <div className="text-[10px] text-espresso/60 uppercase tracking-wider font-sans">
                  Selected: {formatDisplayDate(startDate)} {endDate ? `to ${formatDisplayDate(endDate)}` : "(Select check-out date)"}
                </div>
                {endDate && (
                  <button
                    type="button"
                    onClick={() => setIsOpen(false)}
                    className="w-full bg-gold-deep text-ivory py-3 uppercase tracking-luxury text-[10px] font-medium font-sans border border-gold-deep"
                  >
                    Confirm Dates
                  </button>
                )}
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
}
