"use client";
import { useState, useRef, useEffect } from "react";
import { ChevronLeft, ChevronRight, Calendar } from "lucide-react";
import { PRIMARY_COLOR, type CSSPropertiesWithVars } from "@/lib/common";

interface DatePickerProps {
  label?: string;
  value?: string | Date | null;
  onChange: (date: Date) => void;
  error?: string;
  onBlur?: () => void;
  className?: string;
}

export default function DatePicker({ label = "Select Date", value, onChange, error, onBlur, className = "" }: DatePickerProps) {
  const [show, setShow] = useState(false);
  
  // Convert value to Date object if it's a string
  const selectedDate = value 
    ? (typeof value === 'string' ? new Date(value) : value instanceof Date ? value : null)
    : null;
  
  // Initialize currentMonth with selected date or today
  const [currentMonth, setCurrentMonth] = useState(
    selectedDate && !isNaN(selectedDate.getTime()) ? selectedDate : new Date()
  );
  const pickerRef = useRef<HTMLDivElement>(null);
  const calendarRef = useRef<HTMLDivElement>(null);
  const blurTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  
  // Update currentMonth when value changes
  useEffect(() => {
    const date = value 
      ? (typeof value === 'string' ? new Date(value) : value instanceof Date ? value : null)
      : null;
    if (date && !isNaN(date.getTime())) {
      setCurrentMonth(new Date(date));
    }
  }, [value]);

  const handleDayClick = (day: Date) => {
    onChange(day);
    setShow(false);
  };

  const daysInMonth = (date: Date) => {
    return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
  };

  const firstDayOfMonth = (date: Date) => {
    return new Date(date.getFullYear(), date.getMonth(), 1).getDay();
  };

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

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

  // Handle blur event - only trigger validation when calendar is closed and focus leaves the component
  const handleBlur = (e: React.FocusEvent<HTMLDivElement>) => {
    // Clear any pending blur timeout
    if (blurTimeoutRef.current) {
      clearTimeout(blurTimeoutRef.current);
    }

    // Check if the related target (where focus is moving to) is inside the calendar
    const relatedTarget = e.relatedTarget as Node | null;
    const isFocusMovingToCalendar = relatedTarget && calendarRef.current?.contains(relatedTarget);
    
    // If focus is moving to calendar or calendar is open, don't trigger validation
    if (isFocusMovingToCalendar || show) {
      return;
    }

    // Use setTimeout to check if focus moved to calendar dropdown
    blurTimeoutRef.current = setTimeout(() => {
      // Check if calendar is still open or if focus moved to calendar
      const activeElement = document.activeElement;
      const isFocusInCalendar = calendarRef.current?.contains(activeElement);
      
      // Only call onBlur if calendar is closed and focus is not in calendar
      if (!show && !isFocusInCalendar && onBlur) {
        onBlur();
      }
    }, 150);
  };

  // Prevent blur when clicking inside calendar
  const handleCalendarMouseDown = (e: React.MouseEvent) => {
    // Prevent the input from losing focus when clicking inside calendar
    e.preventDefault();
  };

  // Close when clicking outside
  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      if (pickerRef.current && !pickerRef.current.contains(e.target as Node)) {
        setShow(false);
        // Call onBlur when calendar closes due to outside click
        if (onBlur) {
          // Small delay to ensure blur happens after calendar closes
          setTimeout(() => {
            onBlur();
          }, 100);
        }
      }
    };
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
      if (blurTimeoutRef.current) {
        clearTimeout(blurTimeoutRef.current);
      }
    };
  }, [onBlur, show]);

  const displayValue = selectedDate && !isNaN(selectedDate.getTime()) 
    ? selectedDate.toLocaleDateString() 
    : "";

  return (
    <div className={`relative w-full ${className}`} ref={pickerRef}>
      {label && (
        <label className={`mb-1 text-xs font-semibold uppercase tracking-wide ${error ? "text-red-600" : "text-gray-600"}`}>
          {label}
        </label>
      )}

      {/* Input */}
      <div
        onClick={() => setShow(true)}
        onBlur={(e) => {
          // Handle styling
          if (!error) {
            e.currentTarget.style.borderColor = "";
            e.currentTarget.style.boxShadow = "";
          }
          // Call the main blur handler
          handleBlur(e);
        }}
        tabIndex={0}
        className={`group flex items-center justify-between border rounded-lg px-3 py-1.5 min-h-[2.25rem] bg-white cursor-pointer transition-all duration-200 ease-in-out ${
          error 
            ? "border-red-400 focus:border-red-500 focus:ring-red-400/40" 
            : "border-gray-200 hover:border-[#428B4D]/60 focus:border-[#428B4D] focus:ring-1 focus:ring-[#428B4D]/15"
        }`}
        style={(!error ? {
          "--hover-border": `${PRIMARY_COLOR}80`,
          "--focus-border": PRIMARY_COLOR,
          "--focus-ring": `${PRIMARY_COLOR}66`,
        } : {}) as CSSPropertiesWithVars}
        onMouseEnter={(e) => {
          if (!error && document.activeElement !== e.currentTarget) {
            e.currentTarget.style.borderColor = `${PRIMARY_COLOR}99`;
          }
        }}
        onMouseLeave={(e) => {
          if (!error && document.activeElement !== e.currentTarget) {
            e.currentTarget.style.borderColor = "";
          }
        }}
        onFocus={(e) => {
          if (!error) {
            e.currentTarget.style.borderColor = PRIMARY_COLOR;
            e.currentTarget.style.boxShadow = `0 0 0 1px ${PRIMARY_COLOR}15`;
          }
        }}
      >
        <span className={`text-sm ${displayValue ? "text-gray-800" : "text-gray-400"}`}>
          {displayValue || "Select a date"}
        </span>
        <Calendar className="h-4 w-4 text-gray-500 transition-colors duration-200 group-hover:text-[#428B4D]" />
      </div>
      
      {error && (
        <span className="text-red-500 text-sm mt-1">{error}</span>
      )}

      {show && (
        <div 
          ref={calendarRef} 
          onMouseDown={handleCalendarMouseDown}
          className="absolute z-50 mt-2 w-72 rounded-lg border border-gray-200 bg-white p-4 focus:outline-none"
        >
          {/* Month Header */}
          <div className="flex items-center justify-between mb-4">
            <button 
              type="button"
              onClick={prevMonth} 
              className="p-1 hover:bg-[#428B4D]/10 rounded-lg transition-all duration-200 hover:scale-110 active:scale-95"
            >
              <ChevronLeft className="h-5 w-5 text-gray-600 transition-colors duration-200 hover:text-[#428B4D]" />
            </button>

            <h2 className="font-semibold text-gray-800">
              {currentMonth.toLocaleString("default", { month: "long" })} {currentMonth.getFullYear()}
            </h2>

            <button 
              type="button"
              onClick={nextMonth} 
              className="p-1 hover:bg-[#428B4D]/10 rounded-lg transition-all duration-200 hover:scale-110 active:scale-95"
            >
              <ChevronRight className="h-5 w-5 text-gray-600 transition-colors duration-200 hover:text-[#428B4D]" />
            </button>
          </div>

          {/* Week Days */}
          <div className="grid grid-cols-7 text-center text-sm text-gray-500 font-semibold mb-2">
            {["S", "M", "T", "W", "T", "F", "S"].map((d, index) => (
              <div key={`weekday-${index}`}>{d}</div>
            ))}
          </div>

          {/* Days */}
          <div className="grid grid-cols-7 text-center">
            {[...Array(firstDayOfMonth(currentMonth)).keys()].map((i) => (
              <div key={"empty-" + i}></div>
            ))}

            {[...Array(daysInMonth(currentMonth)).keys()].map((i) => {
              const day = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), i + 1);
              const isSelected = selectedDate?.toDateString() === day.toDateString();

              return (
                <div
                  key={i}
                  onClick={() => handleDayClick(day)}
                  className={`mx-auto my-1 w-9 h-9 flex items-center justify-center rounded-lg cursor-pointer transition-all duration-200
                  ${isSelected 
                    ? "bg-[#428B4D] text-white shadow-md shadow-[#428B4D]/30 scale-105" 
                    : "hover:bg-[#428B4D]/10 text-gray-800 hover:scale-110 active:scale-95"
                  }
                `}
                >
                  {i + 1}
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}
