import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import React__default, { createContext, useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { datePickerTheme } from './DatePicker.theme.js';
import { FormLabel } from '../FormLabel/FormLabel.js';
import { DatePickerTrigger } from './DatePickerTrigger.js';
import { DatePickerBody } from './DatePickerBody.js';
import { DatePickerPresets } from './DatePickerPresets.js';
import { cn } from '../../../utils/cn.js';
import { formatDateCustom } from '../../../utils/dateUtils.js';

const DatePickerContext = createContext(undefined);
/**
 * Format date for display
 * Uses formatString if provided, otherwise falls back to dateFormat (Intl API)
 */
const formatDate = (date, formatString, options = {
    year: "numeric",
    month: "short",
    day: "numeric",
}) => {
    // If formatString is provided, use the custom formatter
    if (formatString) {
        return formatDateCustom(date, formatString);
    }
    // Otherwise use the Intl API
    return date.toLocaleDateString(undefined, options);
};
/**
 * Format date range for display
 */
const formatDateRange = (range, formatString, options) => {
    if (!range.start && !range.end) {
        return "";
    }
    if (range.start && !range.end) {
        return formatDate(range.start, formatString, options);
    }
    if (!range.start && range.end) {
        return formatDate(range.end, formatString, options);
    }
    return `${formatDate(range.start, formatString, options)} - ${formatDate(range.end, formatString, options)}`;
};
/**
 * Main DatePicker Component - follows Select pattern exactly
 */
const DatePickerComponent = React__default.forwardRef(({ id, name, mode = "single", size = "md", state = "default", value, defaultValue, placeholder = "Select date...", disabled = false, required = false, label, helperText, onChange, onFocus, onBlur, minDate, maxDate, isDateDisabled, showToday = true, selectTodayByDefault = false, weekdays, months, dateFormat, formatString, yearRange, presets, className = "", wrapperClassName = "", portal = true, placement = "bottom-start", offset = 4, children, }, ref) => {
    var _a, _b;
    // Merge theme with defaults
    const theme = { ...datePickerTheme };
    // State
    const [isOpen, setIsOpen] = useState(false);
    const [selectedValue, setSelectedValue] = useState(value || defaultValue);
    // Refs
    const triggerRef = useRef(null);
    const contentRef = useRef(null);
    // Update internal state when prop value changes
    useEffect(() => {
        setSelectedValue(value);
    }, [value]);
    // Date selection handler (single mode)
    const handleDateSelect = useCallback((newDate) => {
        if (mode === "single") {
            if (newDate !== selectedValue) {
                setSelectedValue(newDate);
                onChange === null || onChange === void 0 ? void 0 : onChange(newDate);
            }
            setIsOpen(false);
        }
    }, [mode, selectedValue, onChange]);
    // Range selection handler (range mode)
    const handleRangeSelect = useCallback((newRange) => {
        setSelectedValue(newRange);
        onChange === null || onChange === void 0 ? void 0 : onChange(newRange);
        // Don't auto-close anymore - footer Apply button handles this
    }, [onChange]);
    // Button click handler
    const handleButtonClick = useCallback(() => {
        if (!disabled) {
            setIsOpen((prev) => !prev);
        }
    }, [disabled]);
    // Format selected date/range for display
    // formatString takes precedence over dateFormat
    const displayValue = selectedValue
        ? mode === "single" && selectedValue instanceof Date
            ? formatDate(selectedValue, formatString, dateFormat)
            : mode === "range" &&
                typeof selectedValue === "object" &&
                "start" in selectedValue
                ? formatDateRange(selectedValue, formatString, dateFormat)
                : placeholder
        : placeholder;
    // Calendar icon is now built-in to the trigger component
    // Generate a unique ID if not provided
    const generatedId = React__default.useId();
    const datePickerId = id || generatedId;
    // Helper text state style
    const helperTextStateStyle = theme.helperTextStates[state];
    const helperTextStyle = theme.helperTextStyle;
    // Container style
    const containerStyle = theme.containerStyle;
    return (jsx(DatePickerContext.Provider, { value: useMemo(() => ({
            mode,
            isOpen,
            setIsOpen,
            selectedValue,
            setSelectedValue,
            minDate,
            maxDate,
            isDateDisabled,
            showToday,
            selectTodayByDefault,
            weekdays,
            months,
            yearRange,
            handleDateSelect,
            handleRangeSelect,
            size,
            state,
            theme,
            triggerRef,
            contentRef,
        }), [mode, isOpen, selectedValue, minDate, maxDate, isDateDisabled, showToday, selectTodayByDefault, weekdays, months, yearRange, handleDateSelect, handleRangeSelect, size, state, theme]), children: jsxs("div", { ref: ref, className: cn(containerStyle, wrapperClassName), children: [label && (jsx(FormLabel, { htmlFor: datePickerId, required: required, children: label })), jsx(DatePickerTrigger, { id: datePickerId, disabled: disabled, isOpen: isOpen, state: state, size: size, onClick: handleButtonClick, onFocus: onFocus, onBlur: onBlur, className: className, children: jsx("span", { className: cn("block truncate", selectedValue ? theme.valueTextStyle : theme.placeholderTextStyle), children: displayValue }) }), jsx(DatePickerBody, { isOpen: isOpen, onClose: () => setIsOpen(false), portal: portal, placement: placement, offset: offset, presets: presets, children: children }), helperText && (jsx("p", { className: cn(helperTextStyle, helperTextStateStyle), children: helperText })), name && mode === "single" && selectedValue instanceof Date && (jsx("input", { type: "hidden", name: name, value: selectedValue.toISOString() })), name &&
                    mode === "range" &&
                    selectedValue &&
                    typeof selectedValue === "object" &&
                    "start" in selectedValue && (jsxs(Fragment, { children: [jsx("input", { type: "hidden", name: `${name}[start]`, value: ((_a = selectedValue.start) === null || _a === void 0 ? void 0 : _a.toISOString()) || "" }), jsx("input", { type: "hidden", name: `${name}[end]`, value: ((_b = selectedValue.end) === null || _b === void 0 ? void 0 : _b.toISOString()) || "" })] }))] }) }));
});
DatePickerComponent.displayName = "DatePicker";
// Create a compound component with proper typing
const DatePickerWithCompounds = DatePickerComponent;
// Attach compound components
DatePickerWithCompounds.Trigger = DatePickerTrigger;
DatePickerWithCompounds.Body = DatePickerBody;
DatePickerWithCompounds.Presets = DatePickerPresets;

export { DatePickerWithCompounds as DatePicker, DatePickerBody, DatePickerContext, DatePickerPresets, DatePickerTrigger, DatePickerWithCompounds };
