import { jsx, jsxs } from 'react/jsx-runtime';
import React__default, { useContext, useState, useEffect, useCallback, useMemo } from 'react';
import { AnimatePresence, motion } from 'motion/react';
import { createPortal } from 'react-dom';
import { Calendar } from '../../core/Calendar/Calendar.js';
import '../../core/Calendar/CalendarMini/CalendarMini.js';
import { Button } from '../../core/Button/Button.js';
import { cn } from '../../../utils/cn.js';
import { DateRangePickerContext } from './DateRangePicker.js';
import { DateRangePickerPresets } from './DateRangePickerPresets.js';
import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
import { formatDateCustom } from '../../../utils/dateUtils.js';
import { createDropdownAnimations } from '../DatePicker/DatePicker.animations.js';
import { useIsClient } from '../../../hooks/useIsClient.js';
import { useMediaQuery } from '../../../hooks/useMediaQuery.js';

/**
 * Hook to detect dark mode state from document
 */
const useDarkMode = () => {
    const [isDark, setIsDark] = useState(false);
    useEffect(() => {
        if (typeof document === "undefined")
            return;
        const checkDarkMode = () => {
            const hasDarkClass = document.documentElement.classList.contains("dark") ||
                document.body.classList.contains("dark") ||
                document.querySelector(".dark") !== null;
            setIsDark(hasDarkClass);
        };
        checkDarkMode();
        const observer = new MutationObserver(checkDarkMode);
        observer.observe(document.documentElement, {
            attributes: true,
            attributeFilter: ["class"],
        });
        observer.observe(document.body, {
            attributes: true,
            attributeFilter: ["class"],
        });
        return () => observer.disconnect();
    }, []);
    return isDark;
};
/**
 * DateRangePicker Body Component — dual calendars + presets sidebar + footer
 */
const DateRangePickerBody = ({ isOpen, className, onClose, portal = true, placement = "bottom-start", offset = 4, presets, showPresets = true, }) => {
    const context = useContext(DateRangePickerContext);
    if (!context) {
        throw new Error("DateRangePickerBody must be used within a DateRangePicker");
    }
    const { theme, triggerRef, contentRef, selectedRange, minDate, maxDate, isDateDisabled, showToday, weekdays, months, handleRangeSelect, yearRange, } = context;
    const hasPresets = showPresets && presets && presets.length > 0;
    const isDarkMode = useDarkMode();
    const isClient = useIsClient();
    const isMobile = useMediaQuery("(max-width: 639px)");
    // Temp range state — not committed until Apply is clicked
    const [tempRange, setTempRange] = useState(selectedRange);
    // Sync temp range when panel opens
    useEffect(() => {
        if (isOpen) {
            setTempRange(selectedRange);
        }
    }, [isOpen, selectedRange]);
    // Handle preset selection — update calendar view to show the range
    const handlePresetSelect = useCallback((range) => {
        if (range.start) {
            setLeftCalendarDate(new Date(range.start.getFullYear(), range.start.getMonth(), 1));
        }
    }, []);
    // Dual calendar state
    const getInitialLeftDate = () => {
        if (tempRange === null || tempRange === void 0 ? void 0 : tempRange.start) {
            return new Date(tempRange.start.getFullYear(), tempRange.start.getMonth(), 1);
        }
        if (selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.start) {
            return new Date(selectedRange.start.getFullYear(), selectedRange.start.getMonth(), 1);
        }
        return new Date();
    };
    const [leftCalendarDate, setLeftCalendarDate] = useState(getInitialLeftDate);
    const rightCalendarDate = useMemo(() => {
        const nextMonth = new Date(leftCalendarDate);
        nextMonth.setMonth(nextMonth.getMonth() + 1);
        return nextMonth;
    }, [leftCalendarDate]);
    const handleNavigatePrev = useCallback(() => {
        setLeftCalendarDate((prev) => {
            const newDate = new Date(prev);
            newDate.setMonth(newDate.getMonth() - 1);
            return newDate;
        });
    }, []);
    const handleNavigateNext = useCallback(() => {
        setLeftCalendarDate((prev) => {
            const newDate = new Date(prev);
            newDate.setMonth(newDate.getMonth() + 1);
            return newDate;
        });
    }, []);
    // Footer handlers
    const handleApply = useCallback(() => {
        if (tempRange) {
            handleRangeSelect(tempRange);
        }
        onClose === null || onClose === void 0 ? void 0 : onClose();
    }, [tempRange, handleRangeSelect, onClose]);
    const handleCancel = useCallback(() => {
        setTempRange(selectedRange);
        onClose === null || onClose === void 0 ? void 0 : onClose();
    }, [selectedRange, onClose]);
    // Format range for footer display
    const formatRangeDisplay = (range) => {
        if (!(range === null || range === void 0 ? void 0 : range.start) && !(range === null || range === void 0 ? void 0 : range.end))
            return "Select start and end dates";
        if (!range.end)
            return `${formatDateCustom(range.start, "DD/MM/YYYY")} - ...`;
        return `${formatDateCustom(range.start, "DD/MM/YYYY")} - ${formatDateCustom(range.end, "DD/MM/YYYY")}`;
    };
    // Portal positioning
    const { position, cssVariables, contentRef: portalContentRef, isFlipped, isReady, } = useSelectPortal({
        triggerRef,
        isOpen: isOpen || false,
        placement,
        offset,
        autoWidth: true,
    });
    const animations = createDropdownAnimations(isFlipped);
    // Combine refs
    const combinedRef = React__default.useCallback((el) => {
        if (contentRef &&
            typeof contentRef === "object" &&
            "current" in contentRef) {
            contentRef.current =
                el;
        }
        if (portalContentRef &&
            typeof portalContentRef === "object" &&
            "current" in portalContentRef) {
            portalContentRef.current = el;
        }
    }, [contentRef, portalContentRef]);
    // Click outside to close
    useEffect(() => {
        if (!isOpen)
            return;
        const handleClickOutside = (event) => {
            var _a;
            const target = event.target;
            if ((_a = target.closest) === null || _a === void 0 ? void 0 : _a.call(target, '[role="listbox"]')) {
                return;
            }
            const currentContentRef = portal
                ? portalContentRef.current
                : contentRef.current;
            if (currentContentRef &&
                !currentContentRef.contains(target) &&
                triggerRef.current &&
                !triggerRef.current.contains(target)) {
                onClose === null || onClose === void 0 ? void 0 : onClose();
            }
        };
        document.addEventListener("mousedown", handleClickOutside);
        return () => {
            document.removeEventListener("mousedown", handleClickOutside);
        };
    }, [isOpen, onClose, triggerRef, contentRef, portalContentRef, portal]);
    // Escape key
    useEffect(() => {
        if (!isOpen)
            return;
        const handleKeyDown = (event) => {
            if (event.key === "Escape") {
                onClose === null || onClose === void 0 ? void 0 : onClose();
            }
        };
        document.addEventListener("keydown", handleKeyDown);
        return () => {
            document.removeEventListener("keydown", handleKeyDown);
        };
    }, [isOpen, onClose]);
    const contentElement = (jsx(AnimatePresence, { mode: "wait", children: isOpen && (jsxs(motion.div, { ref: combinedRef, className: cn(theme.bodyStyle, className), style: {
                ...cssVariables,
                ...(portal
                    ? {
                        top: `${position.top}px`,
                        left: `${position.left}px`,
                        minWidth: `${position.width}px`,
                    }
                    : {}),
            }, variants: animations, initial: "initial", animate: isReady ? "visible" : "initial", exit: "exit", children: [hasPresets && presets && (jsx(DateRangePickerPresets, { presets: presets, tempRange: tempRange, setTempRange: setTempRange, onPresetSelect: handlePresetSelect })), jsxs("div", { className: "flex flex-col flex-1", children: [jsxs("div", { className: "flex flex-col sm:flex-row justify-between items-center sm:items-start gap-2 sm:gap-6 p-3 sm:p-4", children: [jsx("div", { className: "flex-1 min-w-fit", children: jsx(Calendar, { mode: "range", value: tempRange, onChange: (value) => {
                                            setTempRange(value);
                                        }, viewDate: leftCalendarDate, onViewDateChange: setLeftCalendarDate, onNavigatePrev: handleNavigatePrev, onNavigateNext: isMobile ? handleNavigateNext : null, minDate: minDate, maxDate: maxDate, isDateDisabled: isDateDisabled, showToday: showToday, selectTodayByDefault: false, weekdays: weekdays, months: months, yearRange: yearRange, showOtherMonthDays: false, headerMode: "static", size: "md" }) }), jsx("div", { className: "hidden sm:block flex-1 min-w-fit", children: jsx(Calendar, { mode: "range", value: tempRange, onChange: (value) => {
                                            setTempRange(value);
                                        }, viewDate: rightCalendarDate, onViewDateChange: (newDate) => {
                                            const adjustedLeft = new Date(newDate);
                                            adjustedLeft.setMonth(adjustedLeft.getMonth() - 1);
                                            setLeftCalendarDate(adjustedLeft);
                                        }, onNavigatePrev: null, onNavigateNext: handleNavigateNext, minDate: minDate, maxDate: maxDate, isDateDisabled: isDateDisabled, showToday: showToday, selectTodayByDefault: false, weekdays: weekdays, months: months, yearRange: yearRange, showOtherMonthDays: false, headerMode: "static", size: "md" }) })] }), jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 px-3 sm:px-4 py-3 border-t border-[var(--color-border)]", children: [jsx("div", { className: "text-sm text-center sm:text-left text-[var(--color-text-muted)]", children: formatRangeDisplay(tempRange) }), jsxs("div", { className: "flex w-full sm:w-auto items-center gap-2", children: [jsx(Button, { variant: "outline", color: "neutral", size: "sm", className: "flex-1 sm:flex-initial", onClick: handleCancel, children: "Cancel" }), jsx(Button, { variant: "filled", size: "sm", className: "flex-1 sm:flex-initial", onClick: handleApply, disabled: !(tempRange === null || tempRange === void 0 ? void 0 : tempRange.start) || !(tempRange === null || tempRange === void 0 ? void 0 : tempRange.end), children: "Apply" })] })] })] })] })) }));
    if (portal && isClient) {
        return createPortal(jsx("div", { className: isDarkMode ? "dark" : undefined, children: contentElement }), document.body);
    }
    return contentElement;
};
DateRangePickerBody.displayName = "DateRangePicker.Body";

export { DateRangePickerBody };
