import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import {translate} from '../../../utils';
import {DayRangePicker, DayRangePickerProps} from './DateTimePicker/DayRangePicker';
import lang from '../../../lang/common/index-en_US';

type DateRangePickerWithPresetsProps = {
    timeZoneOffset?: number;
    useDefaultValueFormatter?: boolean;
    todayText?: string;
    todayDateText?: string;
    yesterdayText?: string;
    yesterdayDateText?: string;
    days7Text?: string;
    days30Text?: string;
    days60Text?: string;
    days90Text?: string;
    rangeText?: string;
} & DayRangePickerProps &
    Partial<DateRangePickerWithPresetsDefaultProps>;

type DateRangePickerWithPresetsDefaultProps = {
    useDefaultValueFormatter: boolean;
    todayText: string;
    todayDateText: string;
    yesterdayText: string;
    yesterdayDateText: string;
    days7Text: string;
    days30Text: string;
    days60Text: string;
    days90Text: string;
    rangeText: string;
    timeZoneOffset: number;
};

export class DateRangePickerWithPresets extends React.PureComponent<
    DateRangePickerWithPresetsProps & React.HTMLProps<DateRangePickerWithPresets>
> {
    static propTypes: any = {
        ...DayRangePicker.propTypes,
        timeZoneOffset: PropTypes.number,
        useDefaultValueFormatter: PropTypes.bool,
        todayText: PropTypes.string,
        todayDateText: PropTypes.string,
        yesterdayText: PropTypes.string,
        yesterdayDateText: PropTypes.string,
        days7Text: PropTypes.string,
        days30Text: PropTypes.string,
        days60Text: PropTypes.string,
        days90Text: PropTypes.string,
        rangeText: PropTypes.string
    };

    static defaultProps = {
        useDefaultValueFormatter: true,
        get todayText() {
            return lang.TODAY;
        },
        get todayDateText() {
            return lang.TODAY_DATE;
        },
        get yesterdayText() {
            return lang.YESTERDAY;
        },
        get yesterdayDateText() {
            return lang.YESTERDAY_DATE;
        },
        get days7Text() {
            return lang.DAYS7;
        },
        get days30Text() {
            return lang.DAYS30;
        },
        get days60Text() {
            return lang.DAYS60;
        },
        get days90Text() {
            return lang.DAYS90;
        },
        get rangeText() {
            return lang.RANGE;
        },
        timeZoneOffset: 0
    };

    getCurrentDate() {
        return moment.utc().zone(this.props.timeZoneOffset as any);
    }

    getLocalTime() {
        return {
            NOW: this.getCurrentDate(),
            START_OF_TODAY: this.getCurrentDate(),
            START_OF_YESTERDAY: this.getCurrentDate().add(-1, 'days'),
            START_OF_7_DAYS_AGO: this.getCurrentDate().add(-6, 'days'),
            START_OF_30_DAYS_AGO: this.getCurrentDate().add(-29, 'days'),
            START_OF_60_DAYS_AGO: this.getCurrentDate().add(-59, 'days')
        };
    }

    getRanges = () => {
        const {todayText, yesterdayText, days7Text, days30Text, days60Text} = this.props as any;
        const {
            NOW,
            START_OF_YESTERDAY,
            START_OF_7_DAYS_AGO,
            START_OF_30_DAYS_AGO,
            START_OF_60_DAYS_AGO
        } = this.getLocalTime();

        return {
            [todayText]: {
                startDate: NOW,
                endDate: NOW
            },
            [yesterdayText]: {
                startDate: START_OF_YESTERDAY,
                endDate: START_OF_YESTERDAY
            },
            [days7Text]: {
                startDate: START_OF_7_DAYS_AGO,
                endDate: NOW
            },
            [days30Text]: {
                startDate: START_OF_30_DAYS_AGO,
                endDate: NOW
            },
            [days60Text]: {
                startDate: START_OF_60_DAYS_AGO,
                endDate: NOW
            }
        };
    };

    checkRangeDate({startDate, endDate, daysAgo, endRange}) {
        return (
            startDate
                .clone()
                .add(daysAgo, 'day')
                .isSame(endDate, 'day') && endDate.isSame(endRange, 'day')
        );
    }

    defaultValueFormatter = (startDate, endDate) => {
        const {days7Text, days30Text, days60Text, todayDateText, yesterdayDateText} = this.props;

        const currentDate = this.getCurrentDate();
        const isSelectOneDay = startDate.isSame(endDate, 'date');
        const isStartDateToday = startDate.isSame(currentDate, 'day');
        const isStartDateYesterday = startDate
            .clone()
            .add(1, 'day')
            .isSame(currentDate, 'day');

        const checkHowManyLastDaysSelected = daysAgo =>
            this.checkRangeDate({
                startDate,
                endDate,
                daysAgo,
                endRange: currentDate
            });

        const longDateFormat = moment.localeData().longDateFormat('L');
        const formattedStartDate = startDate.format(longDateFormat);
        const formattedEndDate = endDate.format(longDateFormat);
        if (isSelectOneDay) {
            if (isStartDateToday) {
                return translate(todayDateText as any, {date: formattedStartDate});
            }

            if (isStartDateYesterday) {
                return translate(yesterdayDateText as any, {date: formattedStartDate});
            }

            return startDate.format('L');
        }

        if (checkHowManyLastDaysSelected(6)) {
            return days7Text;
        }
        if (checkHowManyLastDaysSelected(29)) {
            return days30Text;
        }
        if (checkHowManyLastDaysSelected(59)) {
            return days60Text;
        }

        return `${formattedStartDate} - ${formattedEndDate}`;
    };

    getValueFormatter() {
        if (this.props.useDefaultValueFormatter) {
            return this.defaultValueFormatter;
        }

        return this.props.valueFormatter;
    }

    render() {
        const {timeZoneOffset, useDefaultValueFormatter, valueFormatter, ...props} = this.props;
        return (
            <DayRangePicker
                {...props as any}
                ranges={this.getRanges()}
                valueFormatter={this.getValueFormatter()}
            />
        );
    }
}
