import { __read } from "tslib";
import React, { useState, useEffect, useMemo } from "react";
import { parseISO } from "date-fns";
import { weekCalendar, closeBtn, cancelBtn } from "../locale";
import Button from "../../Button";
import { CalendarContainer, WeekContainer, WeekItem, DaysContainer, DaysItem, ButtonContainer } from "../styles";
import { isEqualDates } from "../../utils/date";
import { normalizeDate } from "./helpers";
var checkIsToday = function (_currentDay, _currentMonth, _currentYear, day, month, year) {
    return _currentDay === day && _currentMonth === month && _currentYear === year;
};
var checkIsDisabledDay = function (_dateInISO, minDate, maxDate) {
    var minDay = minDate ? Number(minDate.split(".")[0]) : undefined;
    var minMonth = minDate ? Number(minDate.split(".")[1]) - 1 : undefined;
    var minYear = minDate ? Number(minDate.split(".")[2]) : undefined;
    var maxDay = maxDate ? Number(maxDate.split(".")[0]) : undefined;
    var maxMonth = maxDate ? Number(maxDate.split(".")[1]) - 1 : undefined;
    var maxYear = maxDate ? Number(maxDate.split(".")[2]) : undefined;
    var minDateISO = typeof minYear === "number" &&
        typeof minMonth === "number" &&
        typeof minDay === "number"
        ? new Date(minYear, minMonth, minDay)
        : undefined;
    var maxDateISO = typeof maxYear === "number" &&
        typeof maxMonth === "number" &&
        typeof maxDay === "number"
        ? new Date(maxYear, maxMonth, maxDay)
        : undefined;
    return ((!!minDateISO && _dateInISO < minDateISO) ||
        (!!maxDateISO && maxDateISO < _dateInISO));
};
var CalendarList = function (_a) {
    var hasButtons = _a.hasButtons, locale = _a.locale, daysInMonth = _a.daysInMonth, weekDayNumber = _a.weekDayNumber, daysInPreviousMonth = _a.daysInPreviousMonth, currentMonth = _a.currentMonth, currentYear = _a.currentYear, chosenRange = _a.chosenRange, chooseDate = _a.chooseDate, chosenDate = _a.chosenDate, formattedDate = _a.formattedDate, closeCalendar = _a.closeCalendar, minDate = _a.minDate, maxDate = _a.maxDate, isRangeMode = _a.isRangeMode, onPrevious = _a.onPrevious, onNext = _a.onNext;
    var today = new Date();
    var year = today.getFullYear();
    var month = today.getMonth();
    var day = today.getDate();
    var _b = __read(useState(weekCalendar[locale]), 1), week = _b[0];
    var _c = __read(useState([]), 2), days = _c[0], setDays = _c[1];
    var _d = __read(useState(true), 2), isCloseBtnDisabled = _d[0], setIsCloseBtnDisabled = _d[1];
    var _e = __read(useMemo(function () {
        var chosenDateStart = chosenRange && normalizeDate(chosenRange[0]);
        var startDate = chosenDateStart ? parseISO(chosenDateStart) : null;
        var chosenDateEnd = chosenRange && normalizeDate(chosenRange[1]);
        var endDate = chosenDateEnd ? parseISO(chosenDateEnd) : null;
        if (startDate && endDate && startDate > endDate) {
            return [endDate, startDate];
        }
        return [startDate, endDate];
    }, [chosenRange]), 2), dateRangeStart = _e[0], dateRangeEnd = _e[1];
    var createDaysList = function () {
        var countItemsForCalendar = 42;
        var countDaysForPreviousMonth = weekDayNumber === 0 ? 0 : weekDayNumber - 1;
        var daysList = Array(countItemsForCalendar)
            .fill("")
            .map(function (_day, index) {
            if (index < weekDayNumber) {
                var __day = daysInPreviousMonth - countDaysForPreviousMonth + index;
                var _year = currentMonth === 0 ? currentYear - 1 : currentYear;
                var previousMonth = currentMonth === 0 ? 11 : currentMonth - 1;
                var dateInISO = new Date(_year, previousMonth, __day);
                var date = formattedDate(dateInISO);
                return {
                    date: date,
                    id: index,
                    isActive: chosenRange ? false : chosenDate === date,
                    isDisabled: checkIsDisabledDay(dateInISO, minDate, maxDate),
                    isPrevMonth: true,
                    isToday: checkIsToday(__day, currentMonth, currentYear, day, month, year),
                    isInRange: dateRangeStart &&
                        dateRangeEnd &&
                        dateRangeStart < dateInISO &&
                        dateInISO < dateRangeEnd,
                    isRangeStart: dateRangeStart && isEqualDates(dateRangeStart, dateInISO),
                    isRangeEnd: dateRangeEnd && isEqualDates(dateRangeEnd, dateInISO),
                    day: __day
                };
            }
            else if (index >= weekDayNumber &&
                index <= daysInMonth + (weekDayNumber - 1)) {
                var __day = index - (weekDayNumber - 1);
                var dateInISO = new Date(currentYear, currentMonth, __day);
                var date = formattedDate(dateInISO);
                return {
                    date: date,
                    id: index,
                    isActive: chosenRange ? false : chosenDate === date,
                    isDisabled: checkIsDisabledDay(dateInISO, minDate, maxDate),
                    isToday: checkIsToday(__day, currentMonth, currentYear, day, month, year),
                    isInRange: dateRangeStart &&
                        dateRangeEnd &&
                        dateRangeStart < dateInISO &&
                        dateInISO < dateRangeEnd,
                    isRangeStart: dateRangeStart && isEqualDates(dateRangeStart, dateInISO),
                    isRangeEnd: dateRangeEnd && isEqualDates(dateRangeEnd, dateInISO),
                    day: __day
                };
            }
            else {
                var __day = index - (daysInMonth + weekDayNumber - 1);
                var _year = currentMonth === 11 ? currentYear + 1 : currentYear;
                var nextMonth = currentMonth === 11 ? 0 : currentMonth + 1;
                var dateInISO = new Date(_year, nextMonth, __day);
                var date = formattedDate(dateInISO);
                return {
                    date: date,
                    id: index,
                    isActive: chosenRange ? false : chosenDate === date,
                    isDisabled: checkIsDisabledDay(dateInISO, minDate, maxDate),
                    isNextMonth: true,
                    isToday: checkIsToday(__day, currentMonth, currentYear, day, month, year),
                    isInRange: dateRangeStart &&
                        dateRangeEnd &&
                        dateRangeStart < dateInISO &&
                        dateInISO < dateRangeEnd,
                    isRangeStart: dateRangeStart && isEqualDates(dateRangeStart, dateInISO),
                    isRangeEnd: dateRangeEnd && isEqualDates(dateRangeEnd, dateInISO),
                    day: __day
                };
            }
        });
        setDays(daysList);
    };
    var controlCloseBtnDisabled = function () {
        if (isRangeMode) {
            var isRangeExist = chosenRange && chosenRange.length === 2;
            setIsCloseBtnDisabled(!isRangeExist);
        }
        else {
            var isDateExist = Boolean(chosenDate);
            setIsCloseBtnDisabled(!isDateExist);
        }
    };
    var handleClick = function (date, isDisabled, isActive, isPrevMonth, isNextMonth) {
        if (isDisabled || isActive) {
            return;
        }
        if (!isRangeMode && isPrevMonth) {
            return onPrevious();
        }
        if (!isRangeMode && isNextMonth) {
            return onNext();
        }
        date && chooseDate(date);
        if (!isRangeMode) {
            closeCalendar === null || closeCalendar === void 0 ? void 0 : closeCalendar();
        }
    };
    var handleCloseCalendar = function () {
        if (isCloseBtnDisabled) {
            return;
        }
        closeCalendar === null || closeCalendar === void 0 ? void 0 : closeCalendar();
    };
    var handleCancelCalendar = function () {
        if (isCloseBtnDisabled) {
            return;
        }
        closeCalendar === null || closeCalendar === void 0 ? void 0 : closeCalendar();
    };
    useEffect(function () {
        controlCloseBtnDisabled();
    }, [chosenDate, chosenRange]);
    useEffect(function () {
        createDaysList();
    }, [
        locale,
        daysInMonth,
        weekDayNumber,
        daysInPreviousMonth,
        currentMonth,
        currentYear,
        chosenDate,
        chosenRange,
        minDate,
        maxDate
    ]);
    return (React.createElement(CalendarContainer, null,
        React.createElement(WeekContainer, null, week.map(function (weekday) { return (React.createElement(WeekItem, { key: weekday }, weekday)); })),
        React.createElement(DaysContainer, null, days.map(function (_a, _index) {
            var date = _a.date, _day = _a.day, isActive = _a.isActive, isDisabled = _a.isDisabled, isPrevMonth = _a.isPrevMonth, isNextMonth = _a.isNextMonth, isToday = _a.isToday, isInRange = _a.isInRange, isRangeStart = _a.isRangeStart, isRangeEnd = _a.isRangeEnd, isOuterItem = _a.isOuterItem;
            return (React.createElement(DaysItem, { onClick: function () {
                    return handleClick(date, isDisabled, isActive, isPrevMonth, isNextMonth);
                }, isDisabled: isDisabled, isActive: isActive, isToday: isToday && !isDisabled, isDiffMonth: isPrevMonth || isNextMonth, isInRange: isInRange, isRangeStart: isRangeStart, isRangeEnd: isRangeEnd, isOuterItem: isOuterItem, key: _day.toString() + Math.random() }, _day));
        })),
        isRangeMode && hasButtons && (React.createElement(ButtonContainer, null,
            React.createElement(Button, { viewType: "secondary", width: "140px", onClick: handleCloseCalendar, isDisabled: isCloseBtnDisabled, size: "m" }, cancelBtn[locale]),
            React.createElement(Button, { width: "140px", onClick: handleCancelCalendar, isDisabled: isCloseBtnDisabled, size: "m" }, closeBtn[locale])))));
};
export default CalendarList;
