import React, {FC, useEffect} from "react";
import DatePicker, {CalendarContainerProps} from "react-datepicker";
import classNames from "classnames";
import dayjs from "dayjs";
import customParseFormat from "dayjs/plugin/customParseFormat";

dayjs.extend(customParseFormat);

export type CalendarProps = {
    source: string,
    onChange: (date: string) => void,
    size?: 'normal' | 'small'
}

/**
 * Works with dates in the format: Y-m-d H:i:s
 */
export const Calendar: FC<CalendarProps> = ({source, onChange, size = 'normal'}) => {
    const parseYmdHisDate = (dateString: string): { date: Date, isValid: boolean } => {
        if (!dateString) return {date: dayjs().startOf('day').toDate(), isValid: false};

        const parsed = dayjs(dateString, ['YYYY-MM-DD HH:mm:ss', 'YYYY-MM-DD HH:mm', 'YYYY-MM-DD'], true);

        if (parsed.isValid()) {
            return {date: parsed.toDate(), isValid: true};
        }

        return {date: dayjs().startOf('day').toDate(), isValid: false};
    };

    const formatToYmdHis = (date: Date): string => {
        return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
    };

    const {date: selectedDate, isValid: isValidSourceDate} = parseYmdHisDate(source);

    useEffect(() => {
        if (!isValidSourceDate) {
            onChange(formatToYmdHis(selectedDate));
        }
    }, [isValidSourceDate, source]);

    // Calculate min/max dates dynamically based on the source date
    const getDateRange = () => {
        const sourceDate = dayjs(selectedDate);
        const currentDate = dayjs();

        // Use the earlier date between source and current as the base
        const baseDate = sourceDate.isBefore(currentDate) ? sourceDate : currentDate;

        return {
            minDate: baseDate.subtract(12, 'month').toDate(),
            maxDate: currentDate.add(12, 'month').toDate()
        };
    };

    const { minDate, maxDate } = getDateRange();

    const handleDateChange = (date: Date | null) => {
        if (date) {
            const formattedDate = formatToYmdHis(date);
            onChange(formattedDate);
        }
    };

    return (
        <div className="w-fit">
            <style>{`
                .react-datepicker__navigation {
                    display: none !important;
                }
                .react-datepicker__current-month {
                    display: none !important;
                }
                .react-datepicker__month-year-select {
                    border: none !important;
                    box-shadow: none !important;
                }
            `}</style>
            <DatePicker
                selected={selectedDate}
                onChange={handleDateChange}
                inline
                showMonthYearDropdown={true}
                dateFormatCalendar={"MMMM yyyy"}
                minDate={minDate}
                maxDate={maxDate}
                dropdownMode="select"
                calendarClassName="!w-fit font-sans rounded-2 overflow-hidden border-none [&_.react-datepicker__navigation]:hidden [&_.react-datepicker__current-month]:hidden"
                dayClassName={(date) => classNames("hover:bg-gray-150 !box-content hover:text-gray-600 rounded-1 text-gray-500", {
                    '!bg-blue-normal !text-blue-20': (() => {
                        // noinspection UnnecessaryLocalVariableJS
                        const isSameDay = date.getDate() === selectedDate.getDate() &&
                                         date.getMonth() === selectedDate.getMonth() &&
                                         date.getFullYear() === selectedDate.getFullYear();
                        return isSameDay;
                    })(),
                    'p-[4px]': size === 'normal',
                    '!m-0 p-px text-smaller-1': size === 'small',
                })}
                weekDayClassName={() => "!text-gray-300 !font-regular !text-smaller-1 !uppercase"}
                monthClassName={() => "bg-white font-medium"}
            />
        </div>
    )
}
