import React, { forwardRef, useEffect, useLayoutEffect, useRef, useState } from "react";
import cls from "classnames";
import { useForkRef } from "../../hooks";
import { base, CalendarContainerOverlay, LeftHelper } from "./DateTimePicker.styles";
import { base as sizeCSS } from "./variations/_size/base";
import { base as viewCSS } from "./variations/_view/base";
import { base as hintViewCSS } from "./variations/_hint-view/base";
import { base as hintSizeCSS } from "./variations/_hint-size/base";
import { base as eventTooltipSizeCSS } from "./variations/_tooltip-size/base";
import { base as disabledCSS } from "./variations/_disabled/base";
import { base as readOnlyCSS } from "./variations/_readonly/base";
import { CalendarGrid, DateShortcutList, Input, Popover, StyledSeparator, TimeGrid } from "./ui";
import { classes } from "./DateTimePicker.tokens";
import { useDateTimePicker } from "./hooks/useDateTimePicker";
import { useKeyNavigation } from "./hooks/useKeyboardNavigation";
// changes to start tests
export const dateTimePickerRoot = (Root)=>/*#__PURE__*/ forwardRef(({ className, value: outerValue, defaultDate = '', // variation props
    size, view, readOnly = false, disabled = false, appearance, hasClearDivider, // popover props
    opened: outerOpened, placement = [
        'top',
        'bottom'
    ], offset, frame = 'document', zIndex, closeOnOverlayClick = true, closeOnEsc = true, usePortal = false, // calendar props
    type = 'Days', lang = 'ru', dateFormat = 'DD.MM.YYYY', timeFormat = 'HH:mm:ss', dateTimeSeparator = ' ', maskWithFormat, min, max, renderFromDate, includeEdgeDates, isDouble, dateOnTimeSelectOnly, dateShortcuts, dateShortcutsPlacement = 'left', dateShortcutsWidth, eventTooltipOptions, eventList, disabledList, eventMonthList, disabledMonthList, eventQuarterList, disabledQuarterList, eventYearList, disabledYearList, calendarContainerWidth, calendarContainerHeight, stretched, // input props
    label, labelPlacement = 'outer', keepPlaceholder, requiredPlacement = 'right', required = false, hasRequiredIndicator = false, preserveInvalidOnBlur, placeholder, valueError, valueSuccess, valueEdited, leftHelper, contentLeft, contentRight, textBefore, textAfter, autoComplete, // hint
    hintTrigger = 'hover', hintText, hintView = 'default', hintSize = 'm', hintTargetIcon, hintTargetPlacement = 'outer', hintPlacement = 'auto', hintHasArrow, hintOffset = [
        0,
        0
    ], hintWidth, hintContentLeft, // callbacks
    onChangeValue, onCommitDate, onToggle, onFocus, onBlur, ...rest }, ref)=>{
        const inputRef = useRef(null);
        const inputInnerRef = useForkRef(inputRef, ref);
        const calendarOverlayRef = useRef(null);
        const [isInnerOpen, setIsInnerOpen] = useState(false);
        const openedValue = outerOpened ?? isInnerOpen;
        const { format, dateVisibleValue, calendarGridValue, inputValue, timeVisibleValue, timeColumnsCount, errorClass, successClass, editedClass, handleChangeValue, handleSearch, handleBlur, handleCalendarPick, handleTimePick, updateExternalDate, isDateEqualEdge } = useDateTimePicker({
            inputRef,
            outerValue,
            valueError,
            valueSuccess,
            valueEdited,
            type,
            lang,
            disabled,
            readOnly,
            maskWithFormat,
            dateTimeSeparator,
            dateFormat,
            timeFormat,
            max,
            min,
            includeEdgeDates,
            dateOnTimeSelectOnly,
            onChangeValue,
            onCommitDate,
            onBlur
        });
        const handleCalendarOverlayClick = (event)=>{
            if (disabled || readOnly) {
                return;
            }
            event.stopPropagation();
            if (isInnerOpen && stretched && event.target === calendarOverlayRef?.current) {
                setIsInnerOpen(false);
                if (onToggle) {
                    onToggle(false, event);
                }
            }
        };
        const handleToggle = (innerOpened, event)=>{
            if (disabled || readOnly) {
                return;
            }
            const isCalendarOpen = event?.target === inputRef?.current && event.code !== 'Escape' ? true : innerOpened;
            if (onToggle) {
                onToggle(isCalendarOpen, event);
            }
            setIsInnerOpen(isCalendarOpen);
        };
        const { onKeyDown } = useKeyNavigation({
            opened: isInnerOpen,
            closeOnEsc,
            onToggle: handleToggle
        });
        useEffect(()=>{
            if (disabled || readOnly) {
                setIsInnerOpen(false);
                if (onToggle) {
                    onToggle(false);
                }
            }
        }, [
            disabled,
            readOnly
        ]);
        useLayoutEffect(()=>{
            if (!dateVisibleValue) {
                updateExternalDate(defaultDate);
            }
        }, [
            defaultDate,
            format,
            lang
        ]);
        return /*#__PURE__*/ React.createElement(Root, {
            view: view,
            size: size,
            className: cls(classes.root, className, {
                [classes.stretched]: stretched
            }),
            disabled: disabled,
            readOnly: !disabled && readOnly,
            eventTooltipSize: eventTooltipOptions?.size,
            ...hintText && {
                hintView,
                hintSize
            }
        }, /*#__PURE__*/ React.createElement(Popover, {
            target: /*#__PURE__*/ React.createElement(Input, {
                ref: inputInnerRef,
                className: cls(errorClass, successClass, editedClass),
                value: inputValue,
                size: size,
                label: label,
                labelPlacement: labelPlacement,
                keepPlaceholder: keepPlaceholder,
                requiredPlacement: requiredPlacement,
                required: required,
                hasRequiredIndicator: hasRequiredIndicator,
                preserveInvalidOnBlur: preserveInvalidOnBlur,
                placeholder: placeholder,
                valueError: valueError,
                valueSuccess: valueSuccess,
                valueEdited: valueEdited,
                contentLeft: contentLeft,
                contentRight: contentRight,
                textBefore: textBefore,
                textAfter: textAfter,
                autoComplete: autoComplete,
                readOnly: readOnly,
                disabled: disabled,
                hasClearDivider: appearance === 'clear' && hasClearDivider,
                onChange: handleChangeValue,
                onSearch: (e)=>handleSearch(e?.currentTarget?.value),
                onFocus: onFocus,
                onBlur: handleBlur,
                onKeyDown: onKeyDown,
                ...hintText ? {
                    hintText,
                    hintView,
                    hintSize,
                    hintTrigger,
                    hintTargetIcon,
                    hintPlacement,
                    hintHasArrow,
                    hintOffset,
                    hintWidth,
                    hintContentLeft,
                    hintTargetPlacement
                } : {
                    hintText: undefined
                },
                ...rest
            }),
            opened: openedValue,
            usePortal: usePortal,
            frame: frame,
            offset: offset,
            placement: placement,
            closeOnOverlayClick: closeOnOverlayClick,
            closeOnEsc: closeOnEsc,
            zIndex: zIndex,
            calendarContainerWidth: calendarContainerWidth,
            calendarContainerHeight: calendarContainerHeight,
            onToggle: handleToggle
        }, /*#__PURE__*/ React.createElement(CalendarContainerOverlay, {
            ref: calendarOverlayRef,
            onClick: handleCalendarOverlayClick
        }), /*#__PURE__*/ React.createElement(Root, {
            view: view,
            size: size,
            className: cls(classes.root, className, {
                [classes.stretched]: stretched
            }),
            disabled: disabled,
            readOnly: !disabled && readOnly
        }, dateShortcuts?.length ? /*#__PURE__*/ React.createElement(DateShortcutList, {
            items: dateShortcuts,
            setShortcutDate: handleCalendarPick,
            dateShortcutsWidth: dateShortcutsWidth,
            calendarContainerHeight: calendarContainerHeight,
            dateShortcutsPlacement: dateShortcutsPlacement
        }) : null, /*#__PURE__*/ React.createElement(CalendarGrid, {
            value: calendarGridValue,
            isDouble: isDouble,
            calendarContainerWidth: calendarContainerWidth,
            calendarContainerHeight: calendarContainerHeight,
            type: type,
            eventTooltipOptions: eventTooltipOptions,
            eventList: eventList,
            disabledList: disabledList,
            eventMonthList: eventMonthList,
            disabledMonthList: disabledMonthList,
            eventQuarterList: eventQuarterList,
            disabledQuarterList: disabledQuarterList,
            eventYearList: eventYearList,
            disabledYearList: disabledYearList,
            min: min,
            max: max,
            renderFromDate: renderFromDate,
            includeEdgeDates: includeEdgeDates,
            lang: lang,
            handleCalendarPick: handleCalendarPick
        }), /*#__PURE__*/ React.createElement(StyledSeparator, null), /*#__PURE__*/ React.createElement(TimeGrid, {
            value: timeVisibleValue,
            format: timeFormat,
            columns: timeColumnsCount,
            calendarContainerWidth: calendarContainerWidth,
            calendarContainerHeight: calendarContainerHeight,
            dropdownHeight: calendarContainerHeight,
            onChange: handleTimePick,
            ...isDateEqualEdge(min) && {
                min
            },
            ...isDateEqualEdge(max) && {
                max
            }
        }))), leftHelper && /*#__PURE__*/ React.createElement(LeftHelper, {
            className: cls(errorClass, successClass, editedClass)
        }, leftHelper));
    });
export const dateTimePickerConfig = {
    name: 'DateTimePicker',
    tag: 'div',
    layout: dateTimePickerRoot,
    base,
    variations: {
        view: {
            css: viewCSS
        },
        size: {
            css: sizeCSS
        },
        hintView: {
            css: hintViewCSS
        },
        hintSize: {
            css: hintSizeCSS
        },
        eventTooltipSize: {
            css: eventTooltipSizeCSS
        },
        disabled: {
            css: disabledCSS,
            attrs: true
        },
        readOnly: {
            css: readOnlyCSS,
            attrs: true
        }
    },
    defaults: {
        size: 'm',
        view: 'default',
        hintView: 'default',
        hintSize: 'm'
    }
};
