"use client"

import * as React from "react"
import { CalendarIcon, ChevronDown } from "lucide-react"
import { type DateRange as RDPDateRange, type Matcher } from "react-day-picker"
import { arSA, enUS } from "react-day-picker/locale"

import { cn } from "@/lib/utils"
import { useFormattedDate } from "@/hooks/use-formatted-date"
import { Button } from "@/components/ui/button"
import { Calendar } from "@/components/ui/calendar"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
import { useIsMobile } from "@/hooks/use-mobile"
import { useThemeColors } from "@/hooks/use-theme-colors"
import { locales, type Locale, isSameDay } from "@/lib/date-utils"
import { PresetShortcuts, type DateRange } from "./preset-shortcuts"
import { ScrollArea } from "@/components/ui/scroll-area"
import { DateInput } from "./date-input"

export interface DatepickerProps {
  id?: string
  value?: Date | null
  onChange?: (date: Date | null) => void
  rangeValue?: DateRange | null
  onRangeChange?: (range: DateRange | null) => void
  locale?: Locale
  mode?: "single" | "range"
  showShortcuts?: boolean
  showInput?: boolean
  minDate?: Date
  maxDate?: Date
  label?: string
  disabled?: boolean
  className?: string
}

const DateInputWrapper = React.forwardRef<
  HTMLInputElement,
  {
    value?: Date | null
    onChange?: (date: Date | null) => void
    locale?: Locale
    disabled?: boolean
    minDate?: Date
    maxDate?: Date
    id?: string
    formatValue?: (date: Date) => string
    placeholder?: string
  } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'>
>(({ value, onChange, locale, disabled, minDate, maxDate, id, formatValue, placeholder, ...props }, ref) => {
  return (
    <DateInput
      ref={ref}
      value={value || null}
      onChange={onChange || (() => {})}
      locale={locale || "en"}
      formatValue={formatValue}
      placeholder={placeholder}
      disabled={disabled}
      minDate={minDate}
      maxDate={maxDate}
      id={id}
      {...props}
    />
  )
})

DateInputWrapper.displayName = "DateInputWrapper"

export function Datepicker({
  id,
  value,
  onChange,
  rangeValue,
  onRangeChange,
  locale = "en",
  mode = "single",
  showShortcuts = true,
  showInput = false,
  minDate,
  maxDate,
  label,
  disabled = false,
  className,
}: DatepickerProps) {
  const isMobile = useIsMobile()
  const colors = useThemeColors()
  const config = locales[locale]
  const isRTL = config.direction === "rtl"
  const rdpLocale = locale === "ar" ? arSA : enUS
  const { formatDate, dateFormat } = useFormattedDate()

  const [isOpen, setIsOpen] = React.useState(false)
  const [pendingDate, setPendingDate] = React.useState<Date | undefined>(
    value || undefined
  )
  const [pendingRange, setPendingRange] = React.useState<RDPDateRange | undefined>(
    rangeValue ? { from: rangeValue.start, to: rangeValue.end } : undefined
  )

  React.useEffect(() => {
    if (isOpen) {
      setPendingDate(value || undefined)
      setPendingRange(
        rangeValue ? { from: rangeValue.start, to: rangeValue.end } : undefined
      )
    }
  }, [isOpen, value, rangeValue])

  /**
   * Normalize a date to local noon to prevent timezone-shift bugs.
   * react-day-picker creates dates at midnight local time (00:00:00).
   * Midnight local in UTC+3 = 21:00 the previous day in UTC, so any
   * formatting that applies a UTC-based timezone would show the wrong date.
   * Setting the time to noon (12:00:00 local) keeps the date stable
   * across all UTC offsets within ±11 hours.
   */
  const toLocalNoon = (date: Date): Date =>
    new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0)

  const handleSingleSelect = (date: Date | undefined) => {
    setPendingDate(date ? toLocalNoon(date) : undefined)
  }

  const handleRangeSelect = (range: RDPDateRange | undefined) => {
    if (!range) {
      setPendingRange(undefined)
      return
    }
    setPendingRange({
      from: range.from ? toLocalNoon(range.from) : undefined,
      to: range.to ? toLocalNoon(range.to) : undefined,
    })
  }

  const handleConfirm = () => {
    if (mode === "single") {
      onChange?.(pendingDate || null)
    } else {
      if (pendingRange?.from && pendingRange?.to) {
        onRangeChange?.({ start: pendingRange.from, end: pendingRange.to })
      } else {
        onRangeChange?.(null)
      }
    }
    setIsOpen(false)
  }

  const handleShortcutSelect = (range: DateRange) => {
    setPendingRange({ from: range.start, to: range.end })
  }

  const displayValue = React.useMemo(() => {
    if (mode === "single") {
      return value ? formatDate(value) : config.placeholder
    }
    if (rangeValue?.start) {
      if (rangeValue.end && !isSameDay(rangeValue.start, rangeValue.end)) {
        return `${formatDate(rangeValue.start)} - ${formatDate(rangeValue.end)}`
      }
      return formatDate(rangeValue.start)
    }
    return config.placeholder
  }, [value, rangeValue, mode, config.placeholder, formatDate])

  const handleOpenChange = (open: boolean) => {
    if (disabled) return
    setIsOpen(open)
  }

  const calendarDisabled = React.useMemo(() => {
    if (disabled) return true
    const matchers: Matcher[] = []
    if (minDate) {
      // Set to beginning of the day to ensure minDate itself is NOT disabled by "before"
      const startOfMinDate = new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), 0, 0, 0, 0)
      matchers.push({ before: startOfMinDate })
    }
    if (maxDate) {
      // Set to end of the day to ensure maxDate itself is NOT disabled by "after"
      const endOfMaxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate(), 23, 59, 59, 999)
      matchers.push({ after: endOfMaxDate })
    }
    return matchers.length > 0 ? matchers : undefined
  }, [disabled, minDate, maxDate])

  const CalendarContent = (
    <div
      className={cn(
        "flex flex-col sm:flex-row h-full sm:h-auto",
        isRTL && "sm:flex-row-reverse"
      )}
    >
      {showShortcuts && (
        <div className="w-full sm:w-48 border-b sm:border-b-0 sm:border-e p-4 hidden sm:block bg-background/50">
          <PresetShortcuts onSelect={handleShortcutSelect} locale={locale} />
        </div>
      )}

      <div className="flex flex-col flex-1 p-2 sm:p-4 min-w-0 bg-popover items-center sm:items-stretch">
        {mode === "single" ? (
          <Calendar
            mode="single"
            selected={pendingDate}
            onSelect={handleSingleSelect}
            disabled={calendarDisabled}
            initialFocus
            numberOfMonths={isMobile ? 1 : 1}
            fromDate={minDate}
            toDate={maxDate}
            fromYear={1900}
            toYear={2100}
            captionLayout="dropdown"
            dir={isRTL ? "rtl" : "ltr"}
            locale={rdpLocale}
            className={cn(
              "p-0",
              !isMobile && "[--cell-size:40px]",
              isMobile && "w-full [--cell-size:12vw] xs:[--cell-size:48px]"
            )}
            classNames={{
              root: cn(isMobile && "w-full flex justify-center"),
              months: cn(isMobile && "w-full"),
              month: cn(isMobile && "w-full"),
              table: cn(isMobile && "w-full border-collapse"),
              dropdowns: cn(
                "flex items-center justify-center gap-2",
                isMobile ? "text-sm font-semibold h-full" : "text-xs font-medium"
              ),
              dropdown_root: cn(
                "relative rounded-lg border border-input h-8 flex items-center px-2 transition-colors",
                isMobile ? "bg-background/50" : "bg-background text-xs"
              ),
            }}
          />
        ) : (
          <Calendar
            mode="range"
            selected={pendingRange}
            onSelect={handleRangeSelect}
            disabled={calendarDisabled}
            initialFocus
            numberOfMonths={isMobile ? 1 : 2}
            fromDate={minDate}
            toDate={maxDate}
            fromYear={1900}
            toYear={2100}
            captionLayout="dropdown"
            dir={isRTL ? "rtl" : "ltr"}
            locale={rdpLocale}
            className={cn(
              "p-0",
              !isMobile && "[--cell-size:46px]",
              isMobile && "w-full [--cell-size:12vw] xs:[--cell-size:48px]"
            )}
            classNames={{
              root: cn(isMobile && "w-full flex justify-center"),
              months: cn(isMobile && "w-full"),
              month: cn(isMobile && "w-full"),
              table: cn(isMobile && "w-full border-collapse"),
              dropdowns: cn(
                "flex items-center justify-center gap-2",
                isMobile ? "text-sm font-semibold h-full" : "text-xs font-medium"
              ),
              dropdown_root: cn(
                "relative rounded-lg border border-input h-8 flex items-center px-2 transition-colors",
                isMobile ? "bg-background/50" : "bg-background text-xs"
              ),
            }}
          />
        )}

        {showShortcuts && isMobile && (
          <div className="mt-4 sm:hidden">
            <PresetShortcuts onSelect={handleShortcutSelect} locale={locale} />
          </div>
        )}

        <div
          className={cn(
            "mt-4 flex gap-2 pt-4 border-t w-full mt-auto",
            isRTL && "flex-row-reverse"
          )}
        >
          <Button onClick={handleConfirm} size={isMobile ? "lg" : "default"} className="flex-1 font-semibold rounded-xl sm:rounded-md">
            {config.confirm}
          </Button>
          <Button
            variant="outline"
            size={isMobile ? "lg" : "default"}
            onClick={() => setIsOpen(false)}
            className="flex-1 font-semibold rounded-xl sm:rounded-md"
          >
            {config.cancel}
          </Button>
        </div>
      </div>
    </div>
  )

  const TriggerButton = (
    <Button
      id={id}
      variant="outline"
      disabled={disabled}
      className={cn(
        "w-full justify-between text-start font-normal h-10 px-3 rounded border-input bg-background dark:bg-transparent transition-all hover:bg-transparent hover:text-foreground",
        !value && !rangeValue && "text-muted-foreground",
        disabled && "opacity-60 cursor-not-allowed",
        className
      )}
      style={{
        borderColor: !disabled && isOpen ? colors.primary : '',
        boxShadow: !disabled && isOpen ? `0 0 0 3px ${colors.primary}30` : ''
      }}
    >
      <div className="flex items-center gap-2 truncate">
        <CalendarIcon className="h-4 w-4 text-muted-foreground shrink-0" />
        <span className="truncate">{displayValue}</span>
      </div>
      <ChevronDown className="h-4 w-4 opacity-50 shrink-0" />
    </Button>
  )

  if (isMobile) {
    return (
      <Drawer open={isOpen} onOpenChange={handleOpenChange}>
        <DrawerTrigger asChild disabled={disabled}>
          {showInput ? (
            <DateInputWrapper
              value={value}
              onChange={onChange}
              locale={locale}
              disabled={disabled}
              minDate={minDate}
              maxDate={maxDate}
              id={id}
              formatValue={(date) => formatDate(date)}
              placeholder={dateFormat}
            />
          ) : (
            TriggerButton
          )}
        </DrawerTrigger>
        <DrawerContent className="max-h-[96vh] bg-background">
          <DrawerHeader className="border-b border-border pb-4 pt-2">
            <DrawerTitle className="text-center text-lg">{label || config.timePeriod}</DrawerTitle>
          </DrawerHeader>
          <div className="overflow-y-auto px-4 pb-12 pt-0 w-full max-w-md mx-auto">
            {CalendarContent}
          </div>
        </DrawerContent>
      </Drawer>
    )
  }

  return (
    <Popover open={isOpen} onOpenChange={handleOpenChange}>
      <PopoverTrigger asChild disabled={disabled}>
        {showInput ? (
          <DateInputWrapper
            value={value}
            onChange={onChange}
            locale={locale}
            disabled={disabled}
            minDate={minDate}
            maxDate={maxDate}
            id={id}
            formatValue={(date) => formatDate(date)}
            placeholder={dateFormat}
          />
        ) : (
          TriggerButton
        )}
      </PopoverTrigger>
      <PopoverContent
        className={cn(
          "p-0 w-auto rounded border-border bg-popover shadow-lg overflow-hidden",
          "animate-in fade-in zoom-in-95 duration-200"
        )}
        align="start"
        sideOffset={8}
      >
        {CalendarContent}
      </PopoverContent>
    </Popover>
  )
}
