"use client";

import { useEffect, useRef, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ClearButton } from "./ClearButton";

/**
 * ThemedDatePicker
 * A brand-themed date picker that replaces the unstyleable native
 * <input type="date"> calendar popup.
 *
 * - Displays the date as "dd-mm-yyyy" but stores it as "yyyy-mm-dd"
 *   (so the value is identical to what the native input produced).
 * - Optional min/max bounds (inclusive) disable out-of-range days.
 * - Shows a clear (✕) button once a date is selected.
 */

const WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
const MONTHS = [
  "January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December",
];

export function parseISODate(value: string): Date | null {
  const m = value?.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!m) return null;
  const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
  return isNaN(d.getTime()) ? null : d;
}

export function toISODate(d: Date): string {
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(
    d.getDate()
  ).padStart(2, "0")}`;
}

export function formatDisplayDate(value: string): string {
  const d = parseISODate(value);
  if (!d) return "";
  return `${String(d.getDate()).padStart(2, "0")}-${String(
    d.getMonth() + 1
  ).padStart(2, "0")}-${d.getFullYear()}`;
}

const isSameDay = (a: Date, b: Date | null) =>
  !!b &&
  a.getFullYear() === b.getFullYear() &&
  a.getMonth() === b.getMonth() &&
  a.getDate() === b.getDate();

// Midnight-normalized comparison for min/max bounds.
const atMidnight = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());

export interface ThemedDatePickerProps {
  placeholder?: string;
  /** Value in "yyyy-mm-dd" format. */
  value: string;
  /** Called with the new "yyyy-mm-dd" value. */
  onChange: (value: string) => void;
  /** Called to clear the value (renders the ✕ button when provided). */
  onClear?: () => void;
  disabled?: boolean;
  /** Optional inclusive bounds in "yyyy-mm-dd" format. */
  minDate?: string;
  maxDate?: string;
}

export default function ThemedDatePicker({
  placeholder = "dd-mm-yyyy",
  value,
  onChange,
  onClear,
  disabled = false,
  minDate,
  maxDate,
}: ThemedDatePickerProps) {
  const [isOpen, setIsOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);
  const selected = parseISODate(value);
  const [viewDate, setViewDate] = useState<Date>(selected || new Date());

  const min = minDate ? parseISODate(minDate) : null;
  const max = maxDate ? parseISODate(maxDate) : null;

  // Keep the visible month in sync when the value changes externally.
  useEffect(() => {
    const d = parseISODate(value);
    if (d) setViewDate(d);
  }, [value]);

  // Close on outside click.
  useEffect(() => {
    const onDoc = (e: MouseEvent) => {
      if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false);
    };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);

  const hasValue = !!value;
  const year = viewDate.getFullYear();
  const month = viewDate.getMonth();
  const firstDay = new Date(year, month, 1).getDay();
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const today = new Date();

  const isOutOfRange = (d: Date) => {
    const day = atMidnight(d);
    if (min && day < atMidnight(min)) return true;
    if (max && day > atMidnight(max)) return true;
    return false;
  };

  const cells: (number | null)[] = [];
  for (let i = 0; i < firstDay; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  return (
    <div className="relative w-full" ref={ref}>
      <button
        type="button"
        disabled={disabled}
        onClick={() => !disabled && setIsOpen((o) => !o)}
        className={`w-full flex items-center border border-[#58585A] rounded-full py-[12px] lg:py-[10px] md:py-[10px] pl-[20px] md:pl-[30px] ${
          hasValue ? "pr-[74px] md:pr-[86px]" : "pr-[45px] md:pr-[50px]"
        } text-[14px] md:text-[16px] outline-none bg-white active:!bg-white focus:!bg-white text-left transition-colors ${
          hasValue ? "text-[#58585A]" : "text-[#828282]"
        } ${disabled ? "opacity-60 cursor-not-allowed !bg-gray-100" : "cursor-pointer"}`}
      >
        {hasValue ? formatDisplayDate(value) : placeholder}
      </button>

      {hasValue && !disabled && (
        <ClearButton
          onClick={onClear}
          className="absolute right-[44px] md:right-[56px] top-1/2 -translate-y-1/2 z-10 !min-h-[22px]"
        />
      )}

      {/* Calendar icon */}
      <div className="absolute right-[18px] md:right-[26px] top-1/2 -translate-y-1/2 pointer-events-none text-[#0097DC]">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <rect x="3" y="4" width="18" height="18" rx="2" stroke="currentColor" strokeWidth="2" />
          <line x1="3" y1="9" x2="21" y2="9" stroke="currentColor" strokeWidth="2" />
          <line x1="8" y1="2" x2="8" y2="6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
          <line x1="16" y1="2" x2="16" y2="6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
        </svg>
      </div>

      <AnimatePresence>
        {isOpen && (
          <motion.div
            initial={{ opacity: 0, y: -8, scale: 0.97 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: -8, scale: 0.97 }}
            transition={{ duration: 0.18 }}
            className="absolute z-50 mt-2 w-[300px] max-w-[92vw] bg-white border border-[#E0E0E0] rounded-[20px] shadow-2xl p-4 left-1/2 -translate-x-1/2"
          >
            {/* Header */}
            <div className="flex items-center justify-between mb-3">
              <button
                type="button"
                onClick={() => setViewDate(new Date(year, month - 1, 1))}
                className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-[#E8F4FB] active:!bg-[#E8F4FB] text-[#0097DC] cursor-pointer"
                aria-label="Previous month"
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                  <path d="M15 18l-6-6 6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </button>
              <span className="text-[15px] font-semibold text-[#58585A]">
                {MONTHS[month]} {year}
              </span>
              <button
                type="button"
                onClick={() => setViewDate(new Date(year, month + 1, 1))}
                className="w-8 h-8 flex items-center justify-center rounded-full hover:bg-[#E8F4FB] active:!bg-[#E8F4FB] text-[#0097DC] cursor-pointer"
                aria-label="Next month"
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
                  <path d="M9 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                </svg>
              </button>
            </div>

            {/* Weekday labels */}
            <div className="grid grid-cols-7 gap-1 mb-1">
              {WEEKDAYS.map((w) => (
                <div key={w} className="text-center text-[11px] font-medium text-[#9CA3AF] py-1">
                  {w}
                </div>
              ))}
            </div>

            {/* Day grid */}
            <div className="grid grid-cols-7 gap-1">
              {cells.map((d, i) => {
                if (d === null) return <div key={i} />;
                const cellDate = new Date(year, month, d);
                const isSel = isSameDay(cellDate, selected);
                const isToday = isSameDay(cellDate, today);
                const outOfRange = isOutOfRange(cellDate);
                return (
                  <button
                    key={i}
                    type="button"
                    disabled={outOfRange}
                    onClick={() => {
                      onChange(toISODate(cellDate));
                      setIsOpen(false);
                    }}
                    className={`h-9 w-9 mx-auto flex items-center justify-center rounded-full text-[14px] transition-colors ${
                      outOfRange
                        ? "text-[#D1D5DB] cursor-not-allowed"
                        : isSel
                        ? "bg-[#0097DC] text-white font-semibold cursor-pointer"
                        : isToday
                        ? "border border-[#0097DC] text-[#0097DC] cursor-pointer"
                        : "text-[#58585A] hover:bg-[#E8F4FB] cursor-pointer"
                    }`}
                  >
                    {d}
                  </button>
                );
              })}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
