import React, { FC, useState, useEffect } from "react";
import { v4 as uuidv4 } from 'uuid';
import Datepicker, { registerLocale }  from 'react-datepicker';
import moment from "moment";
import cx from 'classnames';
import { Icon, Modal } from '@mui/material'
import {Button} from "../../Button"
import {Span} from "../../Span"
import './style.scss'
import TimePickerInputsModal from "./components/TimePickerInputs"
import TimePickerSelectsModal from "./components/TimePickerSelects";
import { DateRangePickerModalProps } from "./DateRangePickerModal.types";

import en from 'date-fns/locale/en-US'; 
import es from 'date-fns/locale/es';
import { useCurrentLang } from "../../../hooks/useLocale";

registerLocale('en', en);
registerLocale('es', es);

const DatePickerModalKey = uuidv4()

function capitalize(str: string | undefined) {
    if (str)
        return (str.charAt(0).toUpperCase() + str.slice(1)).replace('.','')?.trim();
    else
        return ''
}

export const DateRangePickerModal: FC<DateRangePickerModalProps> = ({
    id, 
    timePickerType = "selects",
    startDate, 
    endDate, 
    minDate,
    maxDate,
    customRangeDate,
    dateFormat='MMM DD, yyyy hh:mm A', 
    onChange, 
    className,
    modalClassName, 
    style={},
    showTwoMonths = true,
    withTime = false,
    openDateRangePickerModalAutomatically = true
}) => {
    const locale = useCurrentLang()
    const [open, setOpen] = useState(openDateRangePickerModalAutomatically);
    const [dateStartValue, setDateStartValue] = useState<moment.Moment | null>(startDate && moment(startDate) || null)
    const [dateEndValue, setDateEndValue] = useState<moment.Moment | null>(endDate && moment(endDate) || null)

    const [timeStartValue, setTimeStartValue] = useState<moment.Moment>(startDate && withTime && moment(startDate) || moment().startOf("day"))
    const [timeEndValue, setTimeEndValue] = useState<moment.Moment>(endDate && withTime && moment(endDate) || moment().endOf("day"))

    const [selectionDate, setSelectionDate] = useState<string>(startDate && !endDate ? "end" : "start") 

    switch (dateFormat) {
        case "m/d/Y":
            dateFormat = "MM/DD/YYYY hh:mm A"
            break;
        case "d/m/Y":
            dateFormat = "DD/MM/YYYY hh:mm A"
            break;
        case "Y/m/d":
            dateFormat = "YYYY/MM/DD hh:mm A"
            break;
        default:
    }

    dateFormat = withTime ? dateFormat : dateFormat.replace('hh:mm A','')

    let newMaxDate:moment.Moment|undefined = maxDate && moment(maxDate)

    if(customRangeDate && dateStartValue){
      if(dateStartValue?.clone()?.add(customRangeDate - 1 , 'days').isAfter(moment().endOf('day'))){
        const limitDate:moment.Moment | undefined = dateStartValue?.clone().endOf('day').add(customRangeDate, 'days')
        newMaxDate = newMaxDate?.isAfter(limitDate) ? limitDate : newMaxDate;

      }else{
        newMaxDate = dateStartValue?.clone()?.add(customRangeDate - 1, 'days').endOf("day");
        if (dateEndValue && dateEndValue.isAfter(newMaxDate)){
            setDateEndValue(null)
            setSelectionDate("end")
        }
      }
    }

    const handleClose = () => {
        if (dateStartValue && dateEndValue){
            onChange(dateStartValue, dateEndValue, dateStartValue?.toDate(), dateEndValue?.toDate())
        } else {
            if(dateStartValue && !dateEndValue){
                const dateEnd = moment(dateStartValue).endOf('day')
                setDateEndValue(dateEnd);
                onChange(dateStartValue, dateEnd, dateStartValue?.toDate(), dateEnd.toDate())
            }
            else if (startDate && endDate){
                setDateStartValue(moment(startDate)); 
                setDateEndValue(moment(endDate)); 
                onChange( moment(startDate), moment(endDate), moment(startDate).toDate(), moment(endDate).toDate())
            }
            else {
                const dateStart = moment().startOf('day')
                const dateEnd = moment().endOf('day')
                setDateStartValue(dateStart); 
                setDateEndValue(dateEnd); 
                onChange( dateStart, dateEnd, dateStart.toDate(), dateEnd.toDate())
            }
        }
        setSelectionDate("start")
        setOpen(false)
    };

    let highlightSelectedDates = []
    if(dateStartValue){
        highlightSelectedDates.push(dateStartValue.toDate())
    }
    if(dateEndValue){
        highlightSelectedDates.push(dateEndValue.toDate())
    }

    useEffect(() => {
        if (startDate && endDate){
            setDateStartValue(moment(startDate))
            setDateEndValue(moment(endDate))
            setSelectionDate("start")
            
            if (withTime){
                setTimeStartValue(moment(startDate))
                setTimeEndValue(moment(endDate))
            }
        }
    }, [startDate, endDate])

    return (
        <div className={cx("date-rangepicker-modal-component_wrapper", className)} style={style}>
            <div className={cx("date-rangepicker-modal_input-wrapper")}>
                <input 
                    className="date-rangepicker-modal_input" 
                    value={`${dateStartValue && capitalize(dateStartValue?.locale(locale).format(dateFormat)) || ''} - ${dateEndValue && capitalize(dateEndValue?.locale(locale).format(dateFormat))|| ''}`} 
                    onClick={() => setOpen(true)}
                    readOnly 
                    spellCheck={false}
                />
                <Icon 
                    className="date-rangepicker-modal_icon"
                    onClick={() => setOpen(true)}
                >
                    {"calendar_month"}
                </Icon>
            </div>
            <Modal
                open={open}
                onClose={handleClose}
                //BackdropProps={{style: {backgroundColor: "transparent"}}}
                style={{display:'flex',alignItems:'center',justifyContent:'center'}}
            >
                <div key={DatePickerModalKey} className={cx("modal-wrapper", modalClassName)}>
                    <div className={cx("top-date-selector", !withTime && "top-date-selector-no-time")}>
                        <div 
                            className={cx("date-selector", selectionDate === "start" && "selected-option")} 
                            onClick={() => setSelectionDate("start")}
                        >
                            <div className="selector-option">
                                <Span className={selectionDate === "start" ? "selected-option-title" : "option-title"}>
                                    start
                                </Span>
                                <Span className={selectionDate === "start" ? "selected-option-date" : "option-date"}>
                                    {dateStartValue ? capitalize(dateStartValue.locale(locale).format(dateFormat)) : "select"}
                                </Span>
                            </div>
                            { selectionDate === "start" &&
                                <Icon
                                    className="reset-data_icon"
                                    onClick={()=>{
                                        setDateStartValue(null)
                                        setDateEndValue(null)
                                    }}
                                >
                                    {"cancel"}
                                </Icon>
                            }
                        </div>
                        <div 
                            className={cx("date-selector", selectionDate === "end" && "selected-option")} 
                            onClick={() => setSelectionDate("end")}
                        >
                            <div className="selector-option">
                                <Span className={selectionDate === "end" ? "selected-option-title" : "option-title"}>
                                    end
                                </Span>
                                <Span className={selectionDate === "end" ? "selected-option-date" : "option-date"}>
                                    {dateEndValue ? capitalize(dateEndValue.locale(locale).format(dateFormat)) : "select"}
                                </Span>
                            </div>
                            { selectionDate === "end" &&
                                <Icon 
                                    className="reset-data_icon"
                                    onClick={()=>{
                                        setDateEndValue(null)
                                    }}
                                >
                                    {"cancel"}
                                </Icon>
                            }
                        </div>
                    </div>
                    <div className={cx("mid-date-and-time-selector", showTwoMonths && "two-months-modifier")}>
                        <div className="date-rangepicker-wrapper">
                            <Datepicker
                                inline
                                selectsRange
                                //focusSelectedMonth={true}
                                locale={locale}
                                selected={selectionDate === "start" ? dateStartValue?.toDate() : dateEndValue?.toDate()}
                                startDate={dateStartValue?.toDate()}
                                endDate={dateStartValue && dateEndValue?.toDate()}
                                minDate={minDate && moment(minDate)?.toDate()}
                                maxDate={newMaxDate?.toDate()}
                                monthsShown={showTwoMonths ? 2 : 1}
                                disabledKeyboardNavigation
                                highlightDates={highlightSelectedDates}
                                onChange={(newDates, event) => {
                                    const sDate = moment(newDates[0])
                                    const eDate = newDates[1] ? moment(newDates[1]) : null
                                    if (selectionDate === "start" && sDate && !eDate && !dateEndValue){
                                        setDateStartValue(sDate.set({"hour": timeStartValue.hours(), "minute": timeStartValue.minutes()}))
                                        setSelectionDate("end")
                                    } else if (selectionDate === "start" && sDate && !eDate && dateEndValue){
                                        setDateStartValue(sDate.set({"hour": timeStartValue.hours(), "minute": timeStartValue.minutes()}))
                                        if (sDate.isAfter(dateEndValue)) {
                                            setDateEndValue(null)
                                            setSelectionDate("end")
                                        }
                                    } else if (selectionDate === "end" && sDate && eDate) {
                                        setDateEndValue(eDate.set({"hour": timeEndValue.hours(), "minute": timeEndValue.minutes()}))
                                    } else if (selectionDate === "end" && sDate && !eDate) {
                                        if (sDate.isBefore(dateStartValue)) {
                                            setDateStartValue(sDate.set({"hour": timeStartValue.hours(), "minute": timeStartValue.minutes()}))
                                            setDateEndValue(null)
                                        } else {
                                            setDateEndValue(sDate.set({"hour": timeEndValue.hours(), "minute": timeEndValue.minutes()}))
                                            if (!dateStartValue){
                                                setSelectionDate("start")
                                            }
                                        }
                                    }
                                   
                                }}
                            />
                        </div>
                        { !showTwoMonths && withTime && 
                            <div className="timepicker-wrapper">
                                {timePickerType === "selects" &&
                                    <TimePickerSelectsModal 
                                        date={selectionDate === "start" ? timeStartValue : timeEndValue}
                                        onChange={(momentTime: moment.Moment) => {
                                            if (selectionDate === "start"){
                                                setTimeStartValue(momentTime)
                                                if (dateStartValue){
                                                    setDateStartValue(dateStartValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                                }
                                            } else {
                                                setTimeEndValue(momentTime)
                                                if (dateEndValue) {
                                                    setDateEndValue(dateEndValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                                }
                                            }
                                        }}
                                    />
                                }
                                {timePickerType === "inputs" &&
                                    <TimePickerInputsModal
                                        date={selectionDate === "start" ? timeStartValue : timeEndValue} 
                                        onChange={(momentTime: moment.Moment) => {
                                            if (selectionDate === "start"){
                                                setTimeStartValue(momentTime)
                                                if (dateStartValue){
                                                    setDateStartValue(dateStartValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                                }
                                            } else {
                                                setTimeEndValue(momentTime)
                                                if (dateEndValue) {
                                                    setDateEndValue(dateEndValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                                }
                                            }
                                        }}
                                    />
                                }
                            </div>
                        }
                    </div>         
                    <div className={cx("bottom-buttons", showTwoMonths && withTime && "two-months-buttom-modifier")}>
                        {showTwoMonths && withTime &&
                            <div style={{display: "flex", alignItems: "center"}}>
                                <TimePickerInputsModal 
                                    date={selectionDate === "start" ? timeStartValue : timeEndValue}
                                    withIcon
                                    onChange={(momentTime: moment.Moment) => {
                                        if (selectionDate === "start"){
                                            setTimeStartValue(momentTime)
                                            if (dateStartValue){
                                                setDateStartValue(dateStartValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                            }
                                        } else {
                                            setTimeEndValue(momentTime)
                                            if (dateEndValue) {
                                                setDateEndValue(dateEndValue.set({"hour": momentTime.hours(), "minute": momentTime.minutes()}))
                                            }
                                        }
                                    }}
                                />
                            </div>
                        }
                        <div style={{display: "flex", alignItems: "center"}}>
                            <Button
                                className="btn-cancel"     
                                onClick={() => {
                                    const prevStart = startDate ? moment(startDate) : moment().startOf("day")
                                    const prevEnd = endDate ? moment(endDate) : moment().endOf("day")
                                    setDateStartValue(prevStart)
                                    setDateEndValue(prevEnd)
                                    onChange( prevStart, prevEnd, prevStart.toDate(), prevEnd.toDate())
                                    setOpen(false)
                                }}         
                            >
                                {'cancel'}
                            </Button>
                            <Button
                                style={{marginLeft: "5px"}}
                                onClick={handleClose}
                                className="btn-blue"
                            >
                                {'set'}
                            </Button>
                        </div>
                    </div>
                </div>
            </Modal>
        </div >
    )
}

export default DateRangePickerModal