'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var reactPopper = require('react-popper');
var useClickOutside = require('../../hooks/useClickOutside.js');
var AlertCircle = require('../../icons/AlertCircle.js');
var index$9 = require('../../utils/index.js');
var styles$1 = require('../Field/styles.js');
var index$8 = require('./components/actionButtons/index.js');
var index$7 = require('./components/calendar/index.js');
var utils$1 = require('./components/calendar/utils.js');
var index = require('./components/datePickerNarrow/index.js');
var index$4 = require('./components/header/index.js');
var index$1 = require('./components/input/index.js');
var index$2 = require('./components/selectors/index.js');
var dateUtils = require('./dateUtils.js');
var styles = require('./styles.js');
var utils = require('./utils.js');
var index$3 = require('./components/monthAndYearSelectionHeader/index.js');
var index$6 = require('./components/month/index.js');
var index$5 = require('./components/year/index.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

function DatePicker(props) {
    var _a, _b, _c, _d;
    const { variant, disabled = false, selection = 'single-date', dismissText = 'Dismiss', confirmText = 'Confirm', months = 1, startingDay = 'sunday', placeholder = 'Select Date', narrow = false, locale = 'en_CA', label, hasError = false, errorText, assistText, onBlur, touched, leadingIcon, getInputLabel, 'data-testid': dataTestId, 'data-trackid': dataTrackId, monthAndYearSelection = false, } = props;
    const date = new Date();
    const appendTestId = index$9.getId(dataTestId);
    const appendTrackId = index$9.getId(dataTrackId);
    const [prevSelectedSelector, setPrevSelectedSelector] = React.useState();
    const [selectedSelector, setSelectedSelector] = React.useState();
    const [highlightedRange, setHighlightedRange] = React.useState(null);
    const [currentYear, setCurrentYear] = React.useState(date.getFullYear());
    const [currentMonth, setCurrentMonth] = React.useState(0);
    const nextMonth = utils$1.getNextMonth(currentMonth);
    const [visible, setVisibility] = React.useState(false);
    const [referenceElement, setReferenceElement] = React.useState(null);
    const [popperElement, setPopperElement] = React.useState(null);
    const { containerRef } = useClickOutside.useOnClickOutside(onDismiss);
    const { styles: styles$2, attributes } = reactPopper.usePopper(referenceElement, popperElement, utils.popperOptions);
    const [calenderWithFocus, setCalenderWithFocus] = React.useState('primary');
    const [focusElementIndex, setFocusElementIndex] = React.useState(0);
    const [primaryLength, setPrimaryLength] = React.useState(0);
    const inputRef = React.useRef(null);
    const [showError, setShowError] = React.useState(false);
    const [viewType, setViewType] = React.useState('calendar');
    const [calendarWidth, setCalendarWidth] = React.useState(0);
    const [calendarHeight, setCalendarHeight] = React.useState(0);
    React.useEffect(() => {
        var _a, _b;
        if (viewType === 'calendar') {
            setCalendarWidth((_a = popperElement === null || popperElement === void 0 ? void 0 : popperElement.offsetWidth) !== null && _a !== void 0 ? _a : 0);
            setCalendarHeight((_b = popperElement === null || popperElement === void 0 ? void 0 : popperElement.offsetHeight) !== null && _b !== void 0 ? _b : 0);
        }
    }, [popperElement]);
    const selectors = React.useMemo(() => props.selectors
        ? utils.getSelectors(props.selectors)
        : utils.getSelectors(utils.commonDateSelectors), [(_a = props.selectors) === null || _a === void 0 ? void 0 : _a.length]);
    const showSelectors = React.useMemo(() => props.showSelectors || utils.shouldUseSelectorsProp(selectors), [selectors, props.showSelectors]);
    React.useEffect(() => {
        const composeError = typeof touched === 'undefined' ? hasError : hasError && touched;
        setShowError(composeError);
    }, [hasError, touched]);
    React.useEffect(() => {
        if (!visible) {
            setViewType('calendar');
        }
        const cur = utils.getCurrentMonth(date, props.selectedRange);
        setCurrentMonth(cur);
        props.selectedRange &&
            setCurrentYear((props.selectedRange instanceof Date
                ? props.selectedRange
                : props.selectedRange.start).getFullYear());
        if (inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) {
            if (!visible) {
                inputRef.current.blur();
                onBlur === null || onBlur === void 0 ? void 0 : onBlur();
            }
        }
    }, [visible]);
    React.useEffect(() => {
        if (showSelectors) {
            setSelectedSelector(selectors.find((selector) => selector.value === utils.CommonSelectorValue.custom));
        }
    }, [showSelectors]);
    React.useEffect(() => {
        var _a;
        if (showSelectors &&
            selectedSelector &&
            selectedSelector.value !== utils.CommonSelectorValue.custom) {
            const { dateRange } = selectedSelector;
            if (dateRange) {
                const range = dateRange instanceof Date
                    ? { start: dateRange, end: dateRange }
                    : { start: dateRange.start, end: dateRange.end };
                setHighlightedRange(range);
                setCurrentMonth(range.start.getMonth());
                setCurrentYear(range.start.getFullYear());
                (_a = props.onSelect) === null || _a === void 0 ? void 0 : _a.call(props, range);
                if (selectedSelector.value === utils.CommonSelectorValue.lastMonth) {
                    setCurrentMonth(utils.prevMonth);
                    setCurrentYear(utils.year);
                }
            }
        }
    }, [selectedSelector]);
    React.useEffect(() => {
        setFocusElementIndex(dateUtils.getDaysInMonth(currentMonth, currentYear));
    }, [currentMonth]);
    function handleNextMonth() {
        if (currentMonth === utils.JS_MONTHS.December) {
            setCurrentMonth(0);
            setCurrentYear(currentYear + 1);
        }
        else {
            setCurrentMonth(currentMonth + 1);
        }
    }
    function handlePrevYear() {
        setCurrentYear(currentYear - dateUtils.YEARS_TO_DISPLAY);
    }
    function handleNextYear() {
        setCurrentYear(currentYear + dateUtils.YEARS_TO_DISPLAY);
    }
    function handlePrevMonth() {
        if (currentMonth <= utils.JS_MONTHS.January) {
            setCurrentYear(currentYear - 1);
            setCurrentMonth(utils.JS_MONTHS.December);
        }
        else {
            setCurrentMonth(currentMonth - 1);
        }
    }
    function handleRangeChange(date) {
        var _a, _b, _c, _d, _e;
        setSelectedSelector(selectors.find((selector) => selector.value === utils.CommonSelectorValue.custom));
        if (selection === 'single-date') {
            if ((date.getMonth() > currentMonth && date.getFullYear() >= currentYear) ||
                (date.getMonth() === utils.JS_MONTHS.January &&
                    currentMonth === utils.JS_MONTHS.December)) {
                handleNextMonth();
            }
            if ((date.getMonth() < currentMonth && date.getFullYear() <= currentYear) ||
                (currentMonth === utils.JS_MONTHS.January &&
                    date.getMonth() === utils.JS_MONTHS.December)) {
                handlePrevMonth();
            }
        }
        if (props.selection === 'range') {
            if (!highlightedRange) {
                const range = { start: date, end: date };
                setHighlightedRange(range);
                (_a = props.onSelect) === null || _a === void 0 ? void 0 : _a.call(props, range);
            }
            if (highlightedRange) {
                if (date < highlightedRange.start) {
                    const range = { start: date, end: highlightedRange.start };
                    setHighlightedRange(range);
                    (_b = props.onSelect) === null || _b === void 0 ? void 0 : _b.call(props, range);
                }
                if (date >= highlightedRange.start) {
                    const range = Object.assign(Object.assign({}, highlightedRange), { end: date });
                    setHighlightedRange(range);
                    (_c = props.onSelect) === null || _c === void 0 ? void 0 : _c.call(props, range);
                }
                if (!dateUtils.getIsSameDay(highlightedRange.start, highlightedRange.end)) {
                    const range = { start: date, end: date };
                    setHighlightedRange(range);
                    (_d = props.onSelect) === null || _d === void 0 ? void 0 : _d.call(props, range);
                }
            }
        }
        else {
            const range = { start: date, end: date };
            setHighlightedRange(range);
            (_e = props.onSelect) === null || _e === void 0 ? void 0 : _e.call(props, range);
        }
    }
    function handleInputClick() {
        if (!disabled)
            setVisibility(true);
    }
    function onConfirm() {
        if (highlightedRange) {
            props.onChange(highlightedRange);
        }
        setVisibility(false);
        setPrevSelectedSelector(undefined);
    }
    function onDismiss() {
        setHighlightedRange(null);
        setVisibility(false);
        if (prevSelectedSelector) {
            setSelectedSelector(prevSelectedSelector);
            setPrevSelectedSelector(undefined);
        }
    }
    function handleSelectorChange(selector) {
        setSelectedSelector(selector);
        if (!prevSelectedSelector)
            setPrevSelectedSelector(selectedSelector);
    }
    function formatSelectedRange() {
        if (props.selectedRange instanceof Date) {
            return { start: props.selectedRange, end: props.selectedRange };
        }
        return props.selectedRange;
    }
    function handleCalenderFocusChange(calendar, prevCalender) {
        if (prevCalender === 'primary' && calendar === 'secondary') {
            setFocusElementIndex(0);
        }
        else if (prevCalender === 'secondary' && calendar === 'primary') {
            setFocusElementIndex(primaryLength - 1);
        }
        setCalenderWithFocus(calendar);
    }
    const updateCurrentMonth = (month) => {
        setViewType('calendar');
        setCurrentMonth(month);
    };
    const updateCurrentYear = (year) => {
        setViewType('calendar');
        setCurrentYear(year);
    };
    return (React__default['default'].createElement(styles.DatePickerWrapper, { "data-testid": appendTestId(), "data-trackid": appendTrackId() }, props.narrow ? (React__default['default'].createElement(index.DatePickerNarrow, Object.assign({}, props, { disabled: disabled, selectors: selectors, showSelectors: !!props.showSelectors, selection: (_b = props.selection) !== null && _b !== void 0 ? _b : 'single-date', selectedRange: highlightedRange !== null && highlightedRange !== void 0 ? highlightedRange : formatSelectedRange(), customSelectors: props.customSelectors, defaultSelectorValues: props.defaultSelectorValues, selectedSelector: selectedSelector, variant: variant, month: currentMonth, year: currentYear, startingDay: startingDay, locale: locale, handleChange: handleRangeChange, dismissText: dismissText, confirmText: confirmText, onConfirm: onConfirm, onDismiss: onDismiss, onSelectorClick: handleSelectorChange, eventDates: props.eventDates, minDate: props.minDate, maxDate: props.maxDate, placeholder: props.placeholder, label: props.label }))) : (React__default['default'].createElement("div", { ref: containerRef },
        React__default['default'].createElement("div", { ref: setReferenceElement },
            label && (React__default['default'].createElement(styles$1.LabelWrapper, { disabled: disabled, hasLabel: Boolean(label) },
                React__default['default'].createElement(styles$1.Label, { "data-testid": appendTestId('label'), disabled: disabled }, label))),
            React__default['default'].createElement("div", { ref: inputRef, "data-testid": appendTestId('wrapper') },
                React__default['default'].createElement(index$1.Input, { value: formatSelectedRange(), variant: variant, placeholder: placeholder, visible: visible, disabled: disabled, locale: locale, handleClick: handleInputClick, "data-testid": appendTestId('input'), hasError: showError, leadingIcon: leadingIcon, getInputLabel: getInputLabel })),
            React__default['default'].createElement(styles$1.SupportingText, null,
                Boolean(errorText) && showError && !disabled && (React__default['default'].createElement(styles$1.ErrorMessage, { "data-testid": appendTestId('error') },
                    React__default['default'].createElement(AlertCircle['default'], { width: 20, height: 20 }),
                    errorText)),
                !showError &&
                    (typeof assistText === 'string' ? (React__default['default'].createElement(styles$1.AssistMessage, { "data-testid": appendTestId('message') }, assistText)) : (assistText)))),
        visible && (React__default['default'].createElement(styles.Wrapper, Object.assign({ isVisible: visible, role: "dialog", "aria-modal": "true", "data-testid": appendTestId('dialog'), ref: setPopperElement, style: styles$2.popper }, attributes.popper),
            props.selectors && selection === 'range' && selectedSelector && (React__default['default'].createElement(index$2.Selectors, { narrow: narrow, selectors: selectors, selectedSelector: selectedSelector, handleChange: handleSelectorChange, "data-testid": appendTestId('selectors') })),
            props.showSelectors &&
                selection === 'range' &&
                selectedSelector && (React__default['default'].createElement(index$2.SelectorsOld, { narrow: narrow, defaultSelectorValues: props.defaultSelectorValues, customSelectors: props.customSelectors, selectedSelector: selectedSelector, handleChange: handleSelectorChange, "data-testid": appendTestId('selectors') })),
            React__default['default'].createElement("div", null,
                monthAndYearSelection && selection !== 'range' ? (React__default['default'].createElement(index$3.MonthAndYearSelectionHeader, { currentMonth: currentMonth, currentYear: currentYear, locale: locale, viewType: viewType, handleNextYear: handleNextYear, handlePrevYear: handlePrevYear, handleNextMonth: handleNextMonth, handlePrevMonth: handlePrevMonth, updateViewType: (viewType) => setViewType(viewType), "data-testid": appendTestId('month-and-year-selection-header'), minDate: props.minDate, maxDate: props.maxDate })) : (React__default['default'].createElement(index$4.Header, { selection: selection, currentMonth: currentMonth, nextMonth: nextMonth, currentYear: currentYear, months: months, locale: locale, handleNextMonth: handleNextMonth, handlePrevMonth: handlePrevMonth, "data-testid": appendTestId('header') })),
                viewType === 'year' && (React__default['default'].createElement(index$5.Year, { "data-testid": appendTestId('year-selection'), width: calendarWidth, height: calendarHeight, minimumYear: (_c = props.minDate) === null || _c === void 0 ? void 0 : _c.getFullYear(), maximumYear: (_d = props.maxDate) === null || _d === void 0 ? void 0 : _d.getFullYear(), currentYear: currentYear, updateCurrentYear: updateCurrentYear })),
                viewType === 'month' && (React__default['default'].createElement(index$6.Month, { "data-testid": appendTestId('month-selection'), width: calendarWidth, height: calendarHeight, locale: locale, currentMonth: currentMonth, updateCurrentMonth: updateCurrentMonth })),
                viewType === 'calendar' && (React__default['default'].createElement(React__default['default'].Fragment, null,
                    React__default['default'].createElement(styles.CalendarsWrapper, { "data-testid": appendTestId('calendar') },
                        React__default['default'].createElement(index$7.Calendar, { value: "primary", focusElementIndex: calenderWithFocus === 'primary'
                                ? focusElementIndex
                                : null, selection: selection, selectedRange: highlightedRange || formatSelectedRange(), month: currentMonth, year: currentYear, startingDay: startingDay, locale: locale, eventDates: props.eventDates, handleChange: handleRangeChange, minDate: props.minDate, maxDate: props.maxDate, showSelectors: showSelectors, visible: visible, handlePrevMonth: handlePrevMonth, handleNextMonth: selection === 'single-date'
                                ? handleNextMonth
                                : undefined, hasFocus: calenderWithFocus === 'primary', setCalenderWithFocus: handleCalenderFocusChange, setFocusElementIndex: setFocusElementIndex, setLength: setPrimaryLength }),
                        months === 2 && selection === 'range' && (React__default['default'].createElement(index$7.Calendar, { value: "secondary", focusElementIndex: calenderWithFocus === 'secondary'
                                ? focusElementIndex
                                : null, selection: selection, selectedRange: highlightedRange || formatSelectedRange(), month: utils$1.getNextMonth(currentMonth), year: utils$1.getNextYear(currentMonth, currentYear), startingDay: startingDay, locale: locale, eventDates: props.eventDates, handleChange: handleRangeChange, minDate: props.minDate, maxDate: props.maxDate, showSelectors: showSelectors, visible: visible, handleNextMonth: handleNextMonth, hasFocus: calenderWithFocus === 'secondary', setCalenderWithFocus: handleCalenderFocusChange, setFocusElementIndex: setFocusElementIndex }))),
                    React__default['default'].createElement(index$8.ActionButtons, { "data-testid": appendTestId('action-buttons'), dismissText: dismissText, confirmText: confirmText, onConfirm: onConfirm, onDismiss: onDismiss }))))))))));
}

exports.DatePicker = DatePicker;
