'use strict';

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

var React = require('react');
var useKeyPress = require('../../../../hooks/useKeyPress.js');
var dateUtils = require('../../dateUtils.js');
var index$1 = require('../day/index.js');
var index = require('../dayNameRow/index.js');
var styles = require('./styles.js');
var utils = require('./utils.js');

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

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

function Calendar(props) {
    const [days, setDays] = React.useState([]);
    const [startDay, setStartDay] = React.useState(0);
    const calendarRef = React.useRef(null);
    const startColumn = utils.getStartColumn(props.startingDay, startDay, props.selection);
    const focusRef = React.useRef(null);
    const arrowDownPressed = useKeyPress.useKeyPress('ArrowDown', focusRef);
    const arrowUpPressed = useKeyPress.useKeyPress('ArrowUp', focusRef);
    const arrowLeftPressed = useKeyPress.useKeyPress('ArrowLeft', focusRef);
    const arrowRightPressed = useKeyPress.useKeyPress('ArrowRight', focusRef);
    const enterPressed = useKeyPress.useKeyPress('Enter', focusRef);
    const spacePressed = useKeyPress.useKeyPress('Space', focusRef);
    const [isInitial, setIsInitial] = React.useState(true);
    const gridRef = React.useRef(null);
    const [gridPosition, setGridPosition] = React.useState({
        col: 0,
        row: 0,
    });
    const [arrowUpFlag, setArrowUpFlag] = React.useState(false);
    const [arrowDownFlag, setArrowDownFlag] = React.useState(false);
    React.useEffect(() => {
        if (props.visible) {
            setIsInitial(true);
        }
    }, [props.visible]);
    React.useEffect(() => {
        if (arrowUpPressed &&
            props.focusElementIndex !== null &&
            props.focusElementIndex) {
            if (props.focusElementIndex - 7 < 0) {
                if (props.selection === 'range') {
                    if (props.value === 'primary') {
                        props.handlePrevMonth && props.handlePrevMonth();
                    }
                    props.setCalenderWithFocus &&
                        props.value &&
                        props.setCalenderWithFocus('primary', props.value);
                }
                else {
                    setArrowUpFlag(true);
                    props.handlePrevMonth && props.handlePrevMonth();
                }
            }
            else {
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(props.focusElementIndex - 7);
            }
        }
    }, [arrowUpPressed]);
    React.useEffect(() => {
        if (arrowDownPressed &&
            props.focusElementIndex !== null &&
            props.focusElementIndex) {
            if (props.focusElementIndex + 7 >= days.length) {
                if (props.selection === 'range') {
                    if (props.value === 'secondary') {
                        props.handleNextMonth && props.handleNextMonth();
                    }
                    props.setCalenderWithFocus &&
                        props.value &&
                        props.setCalenderWithFocus('secondary', props.value);
                }
                else {
                    props.handleNextMonth && props.handleNextMonth();
                    setArrowDownFlag(true);
                }
            }
            else {
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(props.focusElementIndex + 7);
            }
        }
    }, [arrowDownPressed]);
    React.useEffect(() => {
        if (arrowLeftPressed &&
            props.focusElementIndex !== null &&
            props.focusElementIndex) {
            if (props.focusElementIndex === 0) {
                if (props.selection === 'range') {
                    if (props.value === 'primary') {
                        props.handlePrevMonth && props.handlePrevMonth();
                    }
                    props.setCalenderWithFocus &&
                        props.value &&
                        props.setCalenderWithFocus('primary', props.value);
                }
                else {
                    props.handlePrevMonth && props.handlePrevMonth();
                    setArrowUpFlag(true);
                }
            }
            else {
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(props.focusElementIndex - 1);
            }
        }
    }, [arrowLeftPressed]);
    React.useEffect(() => {
        if (arrowRightPressed &&
            props.focusElementIndex !== null &&
            props.focusElementIndex) {
            if (props.focusElementIndex === days.length - 1) {
                if (props.selection === 'range') {
                    if (props.value === 'secondary') {
                        props.handleNextMonth && props.handleNextMonth();
                    }
                    props.setCalenderWithFocus &&
                        props.value &&
                        props.setCalenderWithFocus('secondary', props.value);
                }
                else {
                    props.handleNextMonth && props.handleNextMonth();
                    setArrowDownFlag(true);
                }
            }
            else {
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(props.focusElementIndex + 1);
            }
        }
    }, [arrowRightPressed]);
    React.useEffect(() => {
        if (enterPressed || spacePressed) {
            const date = props.focusElementIndex
                ? days[props.focusElementIndex]
                : days[0];
            props.handleChange(date);
            if (date.getMonth() !== props.month) {
                setIsInitial(true);
            }
        }
    }, [enterPressed, spacePressed]);
    React.useEffect(() => {
        const days = dateUtils.getDays(props.month, props.year);
        const startColumn = new Date(props.year, props.month).getDay();
        if (props.selection === 'single-date') {
            const allDays = utils.getAllDays(startColumn, props.month, props.year, props.startingDay);
            setDays(allDays);
            setStartDay(0);
        }
        else {
            setDays(days);
            setStartDay(startColumn || 0);
        }
    }, [props.month, props.year, props.startingDay, props.selection]);
    React.useEffect(() => {
        if (focusRef.current) {
            focusRef.current.focus();
        }
    }, [props.focusElementIndex]);
    React.useEffect(() => {
        var _a;
        (_a = props.setLength) === null || _a === void 0 ? void 0 : _a.call(props, days.length);
    }, [days]);
    React.useEffect(() => {
        if (isInitial && days.length > 0 && props.hasFocus) {
            const focusStartIndex = days.findIndex((date) => props.selectedRange && dateUtils.getIsSameDay(date, props.selectedRange.start));
            // If there is a selected range, we set the start to have focus when the datepicker is opened
            if (focusStartIndex !== -1) {
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(focusStartIndex);
            }
            else if (days.findIndex((date) => dateUtils.getIsToday(date)) !== -1) {
                // If there is no selected range, we set the today to have focus when the datepicker is opened
                const focusTodayIndex = days.findIndex((date) => dateUtils.getIsToday(date));
                props.setFocusElementIndex &&
                    props.setFocusElementIndex(focusTodayIndex);
            }
            else {
                const index = days.findIndex((date) => date.getDate() === 1);
                props.setFocusElementIndex && props.setFocusElementIndex(index);
            }
            setIsInitial(false);
        }
    }, [days.length, props.hasFocus, isInitial]);
    // This useEffect contains logic for the calender if we are only showing a single month at a time
    React.useEffect(() => {
        if (arrowUpFlag) {
            // Set the focus position on the previous month to be in the same column but in the last row
            props.setFocusElementIndex &&
                props.setFocusElementIndex(utils.getIndexFromGridPosition({
                    row: gridPosition.row,
                    col: gridPosition.col,
                }));
            setArrowUpFlag(false);
        }
        else if (arrowDownFlag) {
            // Set the focus position on the next month to be in the same column but in the first row
            props.setFocusElementIndex &&
                props.setFocusElementIndex(utils.getIndexFromGridPosition({ row: 0, col: gridPosition.col }));
            setArrowDownFlag(false);
        }
    }, [arrowDownFlag, arrowUpFlag]);
    React.useEffect(() => {
        if (props.focusElementIndex) {
            const index = () => {
                if (props.focusElementIndex) {
                    return props.focusElementIndex;
                }
                return 0;
            };
            const p = utils.getGridPosition(index(), gridRef);
            p && setGridPosition(p);
        }
    }, [props.focusElementIndex]);
    return (React__default['default'].createElement(styles.CalendarWrapper, { ref: calendarRef },
        props.startingDay !== 'none' &&
            (props.narrow ? (React__default['default'].createElement(styles.NarrowMonth, null, `${dateUtils.getMonthName(props.month, props.locale)} ${props.year}`)) : (React__default['default'].createElement(index.DayNameRow, { startingDay: props.startingDay, narrow: props.narrow, locale: props.locale }))),
        React__default['default'].createElement("div", null,
            React__default['default'].createElement(styles.Dates, { startColumn: startColumn, role: "grid", ref: gridRef }, days.map((day, index) => {
                return (React__default['default'].createElement(index$1.Day, { ref: index === props.focusElementIndex ? focusRef : null, key: day.getDay() + index, selectedRange: props.selectedRange, day: day, width: utils.getDayWidth(calendarRef), currentMonth: props.month, selection: props.selection, hasFocus: index === props.focusElementIndex, isStartDay: props.selectedRange
                        ? dateUtils.getIsSameDay(day, props.selectedRange.start)
                        : false, isEndDay: utils.hasEndRange(day, props.selectedRange), isInRange: props.selectedRange && dateUtils.isInDateRange(props.selectedRange, day)
                        ? true
                        : false, hasEvent: props.eventDates
                        ? props.eventDates.some((e) => dateUtils.getIsSameDay(e.date, day))
                        : false, disabled: utils.isDisabled(day, props.minDate, props.maxDate), onChange: props.handleChange }));
            })))));
}

exports.Calendar = Calendar;
