import { type ReactElement } from "react";
import * as React from "react";
import { format } from "date-fns";
import { CalendarIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Calendar } from "@/components/ui/calendar";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";

/**
 * DatePicker — WealthX Design System
 * Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=73-226
 *
 * Composes Popover + Calendar + Button.
 * Variants:
 *  - Date-only picker (default)
 *  - Date + Time picker (showTimePicker)
 */

export interface DatePickerProps {
  value?: Date;
  onChange?: (date: Date | undefined) => void;
  placeholder?: string;
  /** Show a time input below the calendar */
  showTimePicker?: boolean;
  disabled?: boolean;
  className?: string;
  /** Passed through to Calendar (e.g. fromYear, toYear, captionLayout) */
  calendarProps?: Omit<
    React.ComponentProps<typeof Calendar>,
    "mode" | "selected" | "onSelect"
  >;
}

function DatePicker({
  value,
  onChange,
  placeholder = "Pick a date",
  showTimePicker = false,
  disabled = false,
  className,
  calendarProps,
}: DatePickerProps): ReactElement {
  const [open, setOpen] = React.useState(false);

  function handleDaySelect(day: Date | undefined): void {
    if (!day) {
      onChange?.(undefined);
      return;
    }
    // Preserve existing time when selecting a new day
    if (showTimePicker && value) {
      day.setHours(value.getHours(), value.getMinutes());
    }
    onChange?.(day);
    if (!showTimePicker) setOpen(false);
  }

  function handleTimeChange(e: React.ChangeEvent<HTMLInputElement>): void {
    const [hours, minutes] = e.target.value.split(":").map(Number);
    const next = value ? new Date(value) : new Date();
    next.setHours(hours, minutes, 0, 0);
    onChange?.(next);
  }

  const timeValue = value
    ? `${String(value.getHours()).padStart(2, "0")}:${String(value.getMinutes()).padStart(2, "0")}`
    : "";

  let displayValue: string | undefined;
  if (value && showTimePicker) {
    displayValue = format(value, "dd/MM/yyyy HH:mm");
  } else if (value) {
    displayValue = format(value, "dd/MM/yyyy");
  }

  return (
    <Popover onOpenChange={disabled ? undefined : setOpen} open={open}>
      <PopoverTrigger
        render={
          <Button
            className={cn(
              "w-full justify-start rounded-none font-normal data-[empty=true]:text-muted-foreground",
              // Show open/focus state when the popover is expanded
              "aria-expanded:border-ring aria-expanded:ring-2 aria-expanded:ring-ring/20",
              className,
            )}
            data-empty={!value}
            data-slot="date-picker-trigger"
            disabled={disabled}
            variant="outline"
          />
        }
      >
        <CalendarIcon />
        {value ? displayValue : placeholder}
      </PopoverTrigger>
      <PopoverContent
        align="start"
        className="w-auto rounded-none p-0 shadow-sm"
      >
        <Calendar
          captionLayout="dropdown"
          mode="single"
          onSelect={handleDaySelect}
          selected={value}
          {...calendarProps}
          className={cn(
            "rounded-none border-0 shadow-none",
            calendarProps?.className,
          )}
        />
        {showTimePicker ? (
          <div className="border-t border-border px-3 pb-3 pt-2">
            <label className="mb-1.5 block text-xs font-medium text-muted-foreground">
              Time
              <Input
                className="mt-1.5 h-8"
                onChange={handleTimeChange}
                type="time"
                value={timeValue}
              />
            </label>
          </div>
        ) : null}
      </PopoverContent>
    </Popover>
  );
}

export { DatePicker };
