import React, { FC, useState } from 'react';
import dayjs from 'dayjs';
import localeDataPlugin from 'dayjs/plugin/localeData';
import weekdayPlugin from 'dayjs/plugin/weekday';
import moment from 'moment';
import DayPicker, { DateUtils, RangeModifier } from 'react-day-picker';

dayjs.extend(weekdayPlugin);
dayjs.extend(localeDataPlugin);

export const CLASSNAME = 'DateRangePicker';

export type DatePickerRange = { from: string, to: string };
export type RangePickerCallback = (date: DatePickerRange) => void;

export interface Props {
    onChange: RangePickerCallback;
    data: DatePickerRange;
    reverseMonths?: boolean;
    calendarStartsFrom?: string;
    calendarEndsOn?: string;
}

const CaptionElement: FC<{ date: Date }> = ({ date }) => (
    <div className="DayPicker-Caption">
        <div>{moment.utc(date).format('MMMM YYYY')}</div>
    </div>
);

const WeekdayElement: FC<{ weekday: number }> = ({ weekday }) => (
    <div className="DayPicker-Weekday">
        <abbr>{dayjs().localeData().weekdaysMin()[weekday]}</abbr>
    </div>
);

const DateRangePicker: FC<Props> = ({
    onChange,
    data,
    reverseMonths,
    calendarStartsFrom,
    calendarEndsOn
}) => {
    const from = dayjs(data?.from || '').toDate();
    const to = dayjs(data?.to || '').toDate();
    const startFromDate = new Date(calendarStartsFrom ? calendarStartsFrom.toString() : '');
    const endOnDate = new Date(calendarEndsOn ? calendarEndsOn.toString() : '');
    const [lastSelectedDate, setLastSelectedDate] = useState<RangeModifier>({ from, to });

    const handleDayClick = (day: Date) => {
        if (day > endOnDate)
            return;
        if (day < startFromDate)
            return;
        const range = DateUtils.addDayToRange(day, { from, to });
        onChange({
            from: dayjs(range.from !== null ? range.from : lastSelectedDate.from).toString(),
            to: dayjs(range.to !== null ? range.to : lastSelectedDate.to).toString(),
        });
        setLastSelectedDate(range);
    };

    return (
        <DayPicker
            className={ CLASSNAME }
            numberOfMonths={ 2 }
            selectedDays={ [from, { from, to }] }
            modifiers={ { start: from, end: to } }
            onDayClick={ handleDayClick }
            initialMonth={ from }
            toMonth={ to }
            captionElement={ CaptionElement }
            weekdayElement={ WeekdayElement }
            disabledDays={
                [
                    { after: endOnDate },
                    { before: startFromDate }
                ]
            }
            reverseMonths={ reverseMonths }
            pagedNavigation
        />
    );
};

export default DateRangePicker;
