import React, { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { TimePicker, LocalizationProvider, DatePicker, DateTimePicker } from '@mui/x-date-pickers';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { CalendarTodaySmallIcon } from './DateTimeStyles';
import * as R from 'ramda';
import ro from 'date-fns/locale/ro';
import fr from 'date-fns/locale/fr';
import ru from 'date-fns/locale/ru';
import de from 'date-fns/locale/de';
import enUS from 'date-fns/locale/en-US';
import DateTimeEndAdornment from './DateTimeEndAdornment';
import TextField from '../TextField';
const localeMap = {
    de: de,
    ['en-US']: enUS,
    fr: fr,
    ro: ro,
    ru: ru
};
const defaultComponents = {
    OpenPickerIcon: CalendarTodaySmallIcon
};
const DateTime = ({ dateAdapter = AdapterDateFns, adapterLocale, showPicker = 'date', components, inputProps, format = 'ro', open: origOpen = false, onClose, value: origValue = null, onChange: origOnChange, isClearable, required, disabled, error, helperText, ...rest }) => {
    // Code to serve the "Open/Close" functionality
    const [open, setOpen] = useState(origOpen);
    useLayoutEffect(() => {
        setOpen(origOpen);
    }, [origOpen]);
    const handleOpen = useCallback(() => {
        setOpen(true);
    }, []);
    const handleClose = useCallback(() => {
        setOpen(false);
        if (onClose)
            onClose();
    }, [onClose]);
    // ---------------------------------------------
    // Code to serve the "Clearable" functionality
    const [value, setValue] = useState(origValue);
    useLayoutEffect(() => {
        setValue(origValue);
    }, [origValue]);
    const handleChange = useCallback((value) => {
        const changeValue = origOnChange ?? setValue;
        changeValue(value);
    }, [origOnChange]);
    const internalIsClearable = useMemo(() => Boolean(isClearable) && Boolean(value), [isClearable, value]);
    const handleClear = useCallback(() => {
        handleChange(null);
    }, [handleChange]);
    // ---------------------------------------------
    const mergedComponents = useMemo(() => R.mergeRight(defaultComponents, components), [components]);
    const renderInput = useCallback((params) => {
        const OpenPickerIcon = mergedComponents.OpenPickerIcon;
        return (React.createElement(TextField, { fullWidth: true, ...inputProps, ...params, required: required, error: error, helperText: helperText, endAdornment: React.createElement(DateTimeEndAdornment, { isClearable: internalIsClearable, onClear: handleClear, onOpen: handleOpen, OpenPickerIcon: OpenPickerIcon, disabled: disabled }) }));
    }, [
        disabled,
        error,
        handleClear,
        handleOpen,
        helperText,
        inputProps,
        required,
        internalIsClearable,
        mergedComponents.OpenPickerIcon
    ]);
    const localeUsed = useMemo(() => localeMap[format] ?? adapterLocale ?? localeMap.ro, [format, adapterLocale]);
    const commonProps = { renderInput, open, onClose: handleClose, value, onChange: handleChange, disabled };
    const renderPicker = () => {
        switch (showPicker) {
            case 'dateTime':
                return (React.createElement(DateTimePicker, { components: mergedComponents, ...commonProps, ...rest }));
            case 'time':
                return (React.createElement(TimePicker, { components: mergedComponents, ...commonProps, ...rest }));
            default:
                return (React.createElement(DatePicker, { components: mergedComponents, ...commonProps, ...rest }));
        }
    };
    return (React.createElement(LocalizationProvider, { dateAdapter: dateAdapter, adapterLocale: localeUsed }, renderPicker()));
};
DateTime.propTypes = {
    /**
     * @default AdapterDateFns
     * DateIO adapter class function
     */
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    //@ts-ignore
    dateAdapter: PropTypes.func,
    /**
     * The adapterLocale object/string from the engine you use for displaying the date
     */
    adapterLocale: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    /**
     * Choose the type of picker you want displayed by the component
     * @default 'date'
     */
    showPicker: PropTypes.oneOf(['date', 'dateTime', 'time']),
    /**
     * The components used for each slot. Either a string to use a HTML element or a component.
     */
    components: PropTypes.shape({
        LeftArrowButton: PropTypes.any,
        LeftArrowIcon: PropTypes.any,
        OpenPickerIcon: PropTypes.any,
        RightArrowButton: PropTypes.any,
        RightArrowIcon: PropTypes.any,
        SwitchViewButton: PropTypes.any,
        SwitchViewIcon: PropTypes.any
    }),
    /**
     *  Properties that will be passed to the rendered input. This is a TextField.
     */
    inputProps: PropTypes.object,
    /**
     * A small sample of ISO format names that will be used to display the date.
     * @default 'ro'
     */
    format: PropTypes.oneOf(['de', 'en-US', 'fr', 'ro', 'ru']),
    /**
     * @default null
     * Value of the picker
     */
    value: PropTypes.any,
    /**
     * Callback fired when the value (the selected date) changes @DateIOType.
     */
    onChange: PropTypes.func,
    /**
     * Dedicated button for clearing the value
     */
    isClearable: PropTypes.bool,
    /**
     * @default false
     * Control the popup or dialog open state.
     */
    open: PropTypes.bool,
    /**
     * Callback fired when the popup requests to be closed. Use in controlled mode (see open).
     */
    onClose: PropTypes.func,
    /**
     * If true, the picker and text field are disabled.
     */
    disabled: PropTypes.bool,
    /**
     * If true, the label is displayed in an error state.
     */
    error: PropTypes.bool,
    /**
     * The helper text content.
     */
    helperText: PropTypes.node
};
export default DateTime;
//# sourceMappingURL=DateTime.js.map