import React, { FC, useRef, useState, useEffect } from "react";
import Datepicker from "react-datepicker"
import AreaMenu, { Area, Menu } from '../../AreaMenu';
import cx from 'classnames';

import moment from "moment";
import { Icons } from "../../Icons";

import "../style.scss"
import { TimePickerProps } from "./TimePicker.types";

export const TimePicker: FC<TimePickerProps> = ({
    id,
    value,
    format = 'hh:mm:ss',
    timeIntervals = 30,
    variant = "dropdown",
    style = {},
    className = "",
    placeholder = "",
    onChange,
}) => {
    const inputHourRef = useRef<HTMLInputElement>(null);
    const inputMinutsRef = useRef<HTMLInputElement>(null);
    const [timeValue, setTimeValue] = useState(value && moment(value, format) || null);
    const [hourValue, setHourValue] = useState<number>(timeValue ? timeValue?.format("hh") : null);
    const [minuteValue, setMinuteValue] = useState<number>(timeValue ? timeValue?.format("mm") : null);
    const [AmPm, setAmPm] = useState<string>(timeValue ? timeValue?.format("A") : null);
    const areaMenuRef = useRef<any>()

    useEffect(() => {
        if (value) {
            let newValue: any = moment(value, format);
            setTimeValue(moment(newValue));
            setHourValue(newValue?.format("hh"));
            setMinuteValue(newValue?.format("mm"));
            setAmPm(newValue?.format("A"));
        }
    }, [value]);

    const handle24h = (hour: number, period: string) => {
        let hour24 = 0;
        if (period === "AM") {
            if (hour == 12) {
                hour24 = 0
            } else {
                hour24 = hour
            }
        } else {
            if (hour == 12) {
                hour24 = 12
            } else {
                hour24 = +hour + 12      //without + -> it takes hour as string even though it is set as number
            }
        }
        return hour24
    }

    const handleHourChange = (hourTemp: number) => {
        let hour = hourTemp;

        if (Number.isNaN(hour)) {
            setHourValue(0)
            return
        }
        if (hour <= 0) { hour = 12 }
        if (hour >= 12 && (AmPm === "AM")) { hour = 12 }
        if (hour > 12 && (AmPm === "PM")) { hour = 11 }
        if (hour == 0 && (AmPm === "PM")) { hour = 12 }
        setHourValue(hour)
        const hour24 = handle24h(hour, AmPm)
        const newMoment = moment().set({
            'hour': hour24,
            'minute': minuteValue,
        })
        onChange && onChange(newMoment.toDate(), newMoment)
    }

    const handleMinuteChange = (minuteTemp: number) => {
        let minute = Number.isNaN(minuteTemp) ? 0 : minuteTemp;
        if (minute < 0) {
            minute = 0;
        }
        if (minute > 59) {
            minute = 59;
        }
        setMinuteValue(minute)
        const hour24 = handle24h(hourValue, AmPm)
        const newMoment = moment().set({
            'hour': hour24,
            'minute': minute,
        })
        onChange && onChange(newMoment.toDate(), newMoment)
    }

    const handlePeriodChange = (period: string) => {
        if (period === "AM") {
            setAmPm("AM")
        } else {
            setAmPm("PM")
        }
        const hour24 = handle24h(hourValue, period)
        const newMoment = moment().set({
            'hour': hour24,
            'minute': minuteValue,
        })
        onChange && onChange(newMoment.toDate(), newMoment)
    }

    const handleFocus = (type = 'hour') => {
        if(type === 'hour'){
            inputHourRef?.current?.select();
        } else if (type === 'minuts'){
            inputMinutsRef?.current?.select();
        }
    };

    return (
        <>
            {variant === "dropdown" &&
                <AreaMenu
                    id={id || "timepicker"}
                    ref={areaMenuRef}
                >
                    <Area>
                        <div className={cx("gtc-rc-timepicker_area-dropdown", className)}>
                            <input
                                data-testid="TimePickerInput"
                                style={{ ...{ width: "85px" }, ...style }}
                                className="gtc-rc-timepicker_input"
                                value={timeValue?.format(format) || ''}
                                readOnly
                                spellCheck={false}
                                placeholder={placeholder}
                            />
                            <Icons className="gtc-rc-timepicker_icon" name={"access_time"} size="small" />
                        </div>
                    </Area>
                    <Menu>
                        <div className="gtc-rc-timepicker_menu-dropdown">
                            <Datepicker
                                selected={timeValue?.toDate()}
                                showTimeSelect
                                showTimeSelectOnly
                                onChange={(newTime) => {
                                    setTimeValue(moment(newTime))
                                    onChange && onChange(newTime, moment(newTime))
                                    areaMenuRef.current.close()
                                }}
                                inline
                                timeIntervals={timeIntervals}
                                timeCaption="Time"
                            />
                        </div>
                    </Menu>
                </AreaMenu>
            }

            {variant === "inputs" &&
                <div className={cx("gtc-rc-timePicker-variant-inputs-wrap", className)} data-testid="gtc-rc-timePicker">
                    <Icons className="timePicker-inputs-icon" name="access_time" size="medium" />
                    <input
                        ref={inputHourRef}
                        min={0}
                        max={12}
                        step={1}
                        onFocus={() => handleFocus('hour')}
                        className="timePicker-inputs-time"
                        type="number"
                        value={hourValue ? hourValue?.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false }) : ""}
                        placeholder="12"
                        onChange={event => handleHourChange(parseInt(event.target.value))}
                    />
                    <label className="timePicker-inputs-label">
                        :
                    </label>
                    <input
                        ref={inputMinutsRef}
                        min={0}
                        max={59}
                        step={1}
                        onFocus={() => handleFocus('minuts')}
                        className="timePicker-inputs-time"
                        type="number"
                        value={minuteValue ? minuteValue?.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false }) : ""}
                        onChange={event => handleMinuteChange(parseInt(event.target.value))}
                        placeholder="00"
                    />
                    <select
                        className="timePicker-inputs-AmPmSelect"
                        defaultValue={timeValue?.format("A") === "AM" ? "AM" : "PM"}
                        id="TimePicker_AM/PM"
                        name="AMPM"
                        onChange={event => handlePeriodChange(event.target.value)}
                    >
                        <option value="AM">AM</option>
                        <option value="PM">PM</option>
                    </select>
                </div>
            }
        </>
    )
}
