"use client"
import React, { useState, useMemo, useCallback, useRef } from "react"
import { Calendar as LucideCalendar, ChevronLeft, ChevronRight, Clock, Palmtree } from "lucide-react"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { TimeInput } from "@/components/common/TimeInput"
import { useTranslations, useLocale } from "next-intl"
import type { WorkingHour } from "@/types/stylists"

interface Vacation {
  start: string
  end: string
  reason?: string
  _id?: string
}

interface BookingDateTimeFieldsProps {
  value: {
    date: Date | undefined
    startTime: string
  }
  onChange: (fields: { date: Date | undefined; startTime: string }) => void
  dateError?: string
  workingHours?: WorkingHour[]
  vacations?: Vacation[]
  stylistName?: string
}

// Day name mapping for working hours (0=Sunday, 1=Monday, etc.)
const DAY_NAMES = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"] as const

export function BookingDateTimeFields({
  value,
  onChange,
  dateError,
  workingHours,
  vacations,
  stylistName
}: BookingDateTimeFieldsProps) {
  const [calendarOpen, setCalendarOpen] = useState(false)
  const [currentMonth, setCurrentMonth] = useState(() => {
    const now = new Date()
    return { year: now.getFullYear(), month: now.getMonth() }
  })
  const t = useTranslations()
  const locale = useLocale()

  const hasStylistData = !!(workingHours && workingHours.length > 0)

  // Get today's date at midnight for comparison
  const today = useMemo(() => {
    const d = new Date()
    d.setHours(0, 0, 0, 0)
    return d
  }, [])

  // Check if a date falls within any vacation period
  const isOnVacation = useCallback(
    (date: Date): Vacation | null => {
      if (!vacations || vacations.length === 0) return null
      const checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate())
      const dateTime = checkDate.getTime()
      for (const vac of vacations) {
        const vacStart = new Date(vac.start)
        vacStart.setHours(0, 0, 0, 0)
        const vacEnd = new Date(vac.end)
        vacEnd.setHours(23, 59, 59, 999)
        if (dateTime >= vacStart.getTime() && dateTime <= vacEnd.getTime()) {
          return vac
        }
      }
      return null
    },
    [vacations]
  )

  // Get working hours for a specific day
  const getWorkingHoursForDay = useCallback(
    (date: Date): WorkingHour | null => {
      if (!workingHours || workingHours.length === 0) return null
      const dayName = DAY_NAMES[date.getDay()]
      return workingHours.find(wh => wh.day === dayName && wh.enabled) || null
    },
    [workingHours]
  )

  // Check if a date is a non-working day
  const isNonWorkingDay = useCallback(
    (date: Date): boolean => {
      if (!hasStylistData) return false
      return getWorkingHoursForDay(date) === null
    },
    [hasStylistData, getWorkingHoursForDay]
  )

  // Get calendar days for current month view
  const calendarDays = useMemo(() => {
    const { year, month } = currentMonth
    const firstDay = new Date(year, month, 1)
    const lastDay = new Date(year, month + 1, 0)
    const startDayOfWeek = firstDay.getDay()
    const daysInMonth = lastDay.getDate()

    const days: { date: Date; isOutside: boolean }[] = []

    // Previous month padding
    for (let i = 0; i < startDayOfWeek; i++) {
      const d = new Date(year, month, -startDayOfWeek + i + 1)
      days.push({ date: d, isOutside: true })
    }

    // Current month days
    for (let i = 1; i <= daysInMonth; i++) {
      days.push({ date: new Date(year, month, i), isOutside: false })
    }

    // Next month padding to fill 6 rows
    const remaining = 42 - days.length
    for (let i = 1; i <= remaining; i++) {
      days.push({ date: new Date(year, month + 1, i), isOutside: true })
    }

    return days
  }, [currentMonth])

  // Get time slots for selected date
  const availableTimeSlots = useMemo(() => {
    if (!value.date || !hasStylistData) return []
    const wh = getWorkingHoursForDay(value.date)
    if (!wh) return []
    return wh.slots
  }, [value.date, hasStylistData, getWorkingHoursForDay])

  // Check vacation for selected date
  const selectedDateVacation = useMemo(() => {
    if (!value.date) return null
    return isOnVacation(value.date)
  }, [value.date, isOnVacation])

  // Navigate months
  const goToPrevMonth = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setCurrentMonth(prev => {
      if (prev.month === 0) return { year: prev.year - 1, month: 11 }
      return { ...prev, month: prev.month - 1 }
    })
  }

  const goToNextMonth = (e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setCurrentMonth(prev => {
      if (prev.month === 11) return { year: prev.year + 1, month: 0 }
      return { ...prev, month: prev.month + 1 }
    })
  }

  // Handle date selection
  const handleDateSelect = (date: Date, e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()

    const d = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0)

    // If no stylist data, keep current startTime
    if (!hasStylistData) {
      onChange({ date: d, startTime: value.startTime })
    } else {
      // When stylist data exists, reset startTime so user picks from available slots
      onChange({ date: d, startTime: "" })
    }

    // Close the popover with a small delay to ensure state updates properly
    setTimeout(() => {
      setCalendarOpen(false)
    }, 50)
  }

  // Handle time slot click
  const handleTimeSlotClick = (time: string) => {
    onChange({ ...value, startTime: time })
  }

  // Generate quick time options from a slot range (every 30 min)
  const generateSlotTimes = (start: string, end: string): string[] => {
    const times: string[] = []
    const [startH, startM] = start.split(":").map(Number)
    const [endH, endM] = end.split(":").map(Number)
    const startMinutes = startH * 60 + startM
    const endMinutes = endH * 60 + endM

    for (let m = startMinutes; m < endMinutes; m += 30) {
      const h = Math.floor(m / 60)
      const min = m % 60
      times.push(`${h.toString().padStart(2, "0")}:${min.toString().padStart(2, "0")}`)
    }
    return times
  }

  // Format month/year header
  const monthYearLabel = useMemo(() => {
    const date = new Date(currentMonth.year, currentMonth.month, 1)
    return date.toLocaleDateString(locale, { month: "long", year: "numeric" })
  }, [currentMonth, locale])

  // Day headers (Su, Mo, Tu, etc.)
  const dayHeaders = useMemo(() => {
    // Sunday=0 through Saturday=6
    const days: string[] = []
    for (let i = 0; i < 7; i++) {
      // Jan 7, 2024 is a Sunday
      const refDate = new Date(2024, 0, 7 + i)
      days.push(refDate.toLocaleDateString(locale, { weekday: "short" }).slice(0, 2))
    }
    return days
  }, [locale])

  // Helpers
  const isSameDate = (a: Date, b: Date) =>
    a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()

  // Format the displayed date
  const formattedDate = useMemo(() => {
    if (!value.date) return ""
    return value.date.toLocaleDateString(locale, {
      day: "2-digit",
      month: "long",
      year: "numeric"
    })
  }, [value.date, locale])

  return (
    <div className="space-y-4">
      {/* Date Picker */}
      <div className="group">
        <label className="block text-sm font-medium mb-1 group-focus-within:text-primary-blue">
          {t("calendar.form.date")}
        </label>
        <Popover open={calendarOpen} onOpenChange={setCalendarOpen}>
          <PopoverTrigger asChild>
            <button
              type="button"
              onClick={() => setCalendarOpen(prev => !prev)}
              className="h-12 border border-gray-300 focus:border-primary-blue focus:ring-2 focus:ring-primary-blue/20 px-3 py-2 text-base w-full rounded-sm text-left bg-white flex items-center relative"
            >
              <span className={formattedDate ? "text-gray-900" : "text-gray-400"}>
                {formattedDate || t("calendar.form.datePlaceholder")}
              </span>
              <LucideCalendar className="absolute right-4 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400 pointer-events-none" />
            </button>
          </PopoverTrigger>
          <PopoverContent className="w-auto p-0 z-[100]" align="start" sideOffset={4}>
            <div className="bg-white rounded-lg p-4 min-w-[300px]" onClick={e => e.stopPropagation()}>
              {/* Calendar Header */}
              <div className="flex items-center justify-between mb-3">
                <button
                  type="button"
                  onClick={goToPrevMonth}
                  className="p-1.5 hover:bg-gray-100 rounded-md transition-colors"
                >
                  <ChevronLeft className="w-4 h-4 text-gray-600" />
                </button>
                <span className="text-sm font-semibold text-gray-800 capitalize">{monthYearLabel}</span>
                <button
                  type="button"
                  onClick={goToNextMonth}
                  className="p-1.5 hover:bg-gray-100 rounded-md transition-colors"
                >
                  <ChevronRight className="w-4 h-4 text-gray-600" />
                </button>
              </div>

              {/* Day Headers */}
              <div className="grid grid-cols-7 gap-0 mb-1">
                {dayHeaders.map((day, i) => (
                  <div key={i} className="text-center text-xs font-medium text-gray-500 py-1.5 select-none">
                    {day}
                  </div>
                ))}
              </div>

              {/* Calendar Grid */}
              <div className="grid grid-cols-7 gap-0.5">
                {calendarDays.map(({ date, isOutside }, i) => {
                  const isPast = date < today
                  const isSelected = value.date ? isSameDate(date, value.date) : false
                  const isTodays = isSameDate(date, today)
                  const vacation = !isOutside ? isOnVacation(date) : null
                  const nonWorking = !isOutside ? isNonWorkingDay(date) : false

                  // Determine if this cell is clickable
                  const isClickable = !isOutside && !isPast && (!nonWorking || !hasStylistData || !!vacation)

                  // Build cell classes
                  let cellClasses =
                    "relative flex items-center justify-center w-9 h-9 text-sm rounded-md transition-all duration-150 select-none "

                  if (isOutside) {
                    cellClasses += "text-gray-300 cursor-default "
                  } else if (isPast) {
                    cellClasses += "text-gray-300 cursor-not-allowed "
                  } else if (isSelected) {
                    cellClasses += "bg-[#1B2B65] text-white font-semibold shadow-sm cursor-pointer "
                  } else if (vacation && hasStylistData) {
                    cellClasses += "bg-red-50 text-red-600 hover:bg-red-100 cursor-pointer border border-red-200 "
                  } else if (nonWorking && hasStylistData) {
                    cellClasses += "text-gray-300 cursor-not-allowed line-through "
                  } else if (isTodays) {
                    cellClasses += "bg-gray-100 text-gray-900 font-semibold hover:bg-gray-200 cursor-pointer ring-1 ring-gray-300 "
                  } else {
                    cellClasses += "text-gray-700 hover:bg-blue-50 cursor-pointer "
                  }

                  return (
                    <button
                      key={i}
                      type="button"
                      disabled={!isClickable}
                      onClick={(e) => {
                        if (isClickable) {
                          handleDateSelect(date, e)
                        }
                      }}
                      className={cellClasses}
                      title={
                        vacation && hasStylistData
                          ? `🏖️ ${t("calendar.availability.onVacation")}${vacation.reason ? `: ${vacation.reason}` : ""}`
                          : nonWorking && hasStylistData
                            ? t("calendar.availability.notWorking")
                            : undefined
                      }
                    >
                      {date.getDate()}
                      {/* Vacation dot indicator */}
                      {vacation && hasStylistData && !isSelected && !isOutside && !isPast && (
                        <span className="absolute bottom-0.5 left-1/2 -translate-x-1/2 w-1.5 h-1.5 rounded-full bg-red-400" />
                      )}
                    </button>
                  )
                })}
              </div>

              {/* Legend */}
              {hasStylistData && (
                <div className="flex items-center gap-4 mt-3 pt-3 border-t border-gray-100">
                  <div className="flex items-center gap-1.5">
                    <span className="w-2.5 h-2.5 rounded-full bg-red-400 inline-block flex-shrink-0" />
                    <span className="text-[11px] text-gray-500">{t("calendar.availability.vacation")}</span>
                  </div>
                  <div className="flex items-center gap-1.5">
                    <span className="w-2.5 h-2.5 rounded-full bg-gray-300 inline-block flex-shrink-0" />
                    <span className="text-[11px] text-gray-500">{t("calendar.availability.dayOff")}</span>
                  </div>
                </div>
              )}
            </div>
          </PopoverContent>
        </Popover>
        {dateError && <div className="text-red-500 text-sm mt-1">{dateError}</div>}
      </div>

      {/* Vacation Warning */}
      {selectedDateVacation && hasStylistData && (
        <div className="flex items-start gap-3 p-3 bg-amber-50 border border-amber-200 rounded-lg">
          <Palmtree className="w-5 h-5 text-amber-500 flex-shrink-0 mt-0.5" />
          <div className="flex-1">
            <p className="text-sm font-medium text-amber-800">
              {stylistName
                ? t("calendar.availability.stylistOnVacation", { name: stylistName })
                : t("calendar.availability.onVacation")}
            </p>
            <p className="text-xs text-amber-600 mt-0.5">
              {new Date(selectedDateVacation.start).toLocaleDateString(locale, {
                day: "2-digit",
                month: "short",
                year: "numeric"
              })}{" "}
              →{" "}
              {new Date(selectedDateVacation.end).toLocaleDateString(locale, {
                day: "2-digit",
                month: "short",
                year: "numeric"
              })}
              {selectedDateVacation.reason && ` • ${selectedDateVacation.reason}`}
            </p>
          </div>
        </div>
      )}

      {/* Working Hours Slots - shown when a valid working day is selected */}
      {value.date && hasStylistData && !selectedDateVacation && availableTimeSlots.length > 0 && (
        <div className="space-y-3">
          <div className="flex items-center gap-2">
            <Clock className="w-4 h-4 text-primary-blue" />
            <label className="text-sm font-medium text-gray-700">
              {t("calendar.availability.availableSlots")}
            </label>
          </div>

          <div className="space-y-2">
            {availableTimeSlots.map((slot, idx) => (
              <div key={idx} className="space-y-2">
                {/* Slot range label */}
                <div className="flex items-center gap-2">
                  <span className="text-xs font-medium text-gray-500 bg-gray-50 px-2 py-0.5 rounded">
                    {slot.start} — {slot.end}
                  </span>
                </div>

                {/* Time chips */}
                <div className="flex flex-wrap gap-1.5">
                  {generateSlotTimes(slot.start, slot.end).map(time => (
                    <button
                      key={time}
                      type="button"
                      onClick={() => handleTimeSlotClick(time)}
                      className={`px-3 py-1.5 text-xs rounded-md border transition-all duration-150 font-medium ${value.startTime === time
                        ? "bg-[#1B2B65] text-white border-[#1B2B65] shadow-sm"
                        : "bg-white text-gray-600 border-gray-200 hover:border-[#1B2B65]/40 hover:bg-blue-50 hover:text-[#1B2B65]"
                        }`}
                    >
                      {time}
                    </button>
                  ))}
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Time Input - always show for manual override or when no stylist data */}
      <div className="group">
        <label className="block text-sm font-medium mb-1 group-focus-within:text-primary-blue">
          {t("calendar.form.startTime")}
          {hasStylistData && availableTimeSlots.length > 0 && !selectedDateVacation && (
            <span className="text-xs text-gray-400 font-normal ml-2">
              {t("calendar.availability.orEnterManually")}
            </span>
          )}
        </label>
        <TimeInput
          value={value.startTime}
          onChange={time => onChange({ ...value, startTime: time })}
          className="w-full"
          required
          quickTimes={
            hasStylistData && availableTimeSlots.length > 0 && !selectedDateVacation
              ? availableTimeSlots.map(slot => ({
                label: slot.start,
                value: slot.start
              }))
              : undefined
          }
          minHour={
            hasStylistData && availableTimeSlots.length > 0 && !selectedDateVacation
              ? parseInt(availableTimeSlots[0].start.split(":")[0])
              : undefined
          }
          maxHour={
            hasStylistData && availableTimeSlots.length > 0 && !selectedDateVacation
              ? parseInt(availableTimeSlots[availableTimeSlots.length - 1].end.split(":")[0]) - 1
              : undefined
          }
        />
      </div>
    </div>
  )
}
