import React, { useState, useRef, useEffect, useCallback } from 'react';
import { Calendar as CalendarIcon } from '@carbon/icons-react';
// import locale from "date-fns/locale/en-US";
import useOnClickOutside from './../../../hooks/useClickOutside';
import { twMerge } from 'tailwind-merge';
import Block from '../../atoms/Block';
import Button from '../../atoms/Button';
import InputMasked from '../../elements/InputMasked';
import Calendar from '../Calendar';
import IMask from 'imask/dist/imask';

export interface DatePickerProps {
    /**
     * Value prop that can receive a Date.
     */
    value?: Date;
    /**
     * Disable the input and the calendar
     */
    disabled?: boolean;
    /**
     * Main container className.
     */
    className?: string;
    /**
     * Label text for the DateInput.
     */
    label?: string;
    /**
     * Used to calculate the maximum month to render.
     */
    maxDate?: Date;
    /**
     * Used to calculate the minimum month to render.
     */
    minDate?: Date;
    /**
     * Color variation that will switch between styles for the DatePicker .
     */
    variation?: 'default' | 'primary' | 'secondary';
    /**
     * onChange event that will return a DateObj.
     */

    onChange?: (value: React.SetStateAction<any>) => void;
}

const DatePicker: React.FC<DatePickerProps> = (props) => {
    const {
        value,
        disabled,
        className,
        variation,
        onChange,
        //TODO: Add label min and max date
        // label, maxDate, minDate
    } = props;
    const [showCalendar, setShowCalendar] = useState(false);
    const [date, setDate] = useState<Date | undefined>(value);
    const ref = useRef(null);

    const handleClickOutside = () => {
        setShowCalendar(false);
    };

    const handleOnChange = useCallback(() => {
        if (onChange && date) onChange(date);
    }, [date]);

    useEffect(() => {
        handleOnChange();
    }, [date]);

    useOnClickOutside(ref, handleClickOutside);

    const formatDate = (date: Date | undefined) => {
        const day = String(date?.getDate()).padStart(2, '0');
        const month = String(date && date?.getMonth() + 1).padStart(2, '0');
        const year = date?.getFullYear();
        const stringDate = [day, month, year].join('.');
        return `${stringDate}`;
    };

    const parseToDate = (str: string | number | readonly string[]) => {
        const string = `${str}`;
        const [day, month, year] = string.split('.');
        return new Date(Number(year), Number(month) - 1, Number(day));
    };

    const dateBlock = {
        YYYY: {
            mask: IMask.MaskedRange,
            from: 1000,
            to: 9999,
        },
        MM: {
            mask: IMask.MaskedRange,
            from: 1,
            to: 12,
        },
        DD: {
            mask: IMask.MaskedRange,
            from: 1,
            to: 31,
        },
    };

    return (
        //TODO: Add block and ref instead of the div
        <div ref={ref} className={twMerge(`relative w-full ${className ? className : ''}`)}>
            <Block className="relative z-20 flex">
                <InputMasked
                    variation={variation}
                    mask={Date}
                    value={date && formatDate(date)}
                    blocks={dateBlock}
                    format={formatDate}
                    parse={parseToDate}
                    onComplete={(value) => value && setDate(parseToDate(value))}
                    onAccept={(value) => !value && setDate(undefined)}
                    placeholder="dd.mm.yyyy"
                    autofix={true}
                    disabled={disabled}
                />
                <Button
                    disabled={disabled}
                    variation={variation}
                    onClick={() => setShowCalendar(!showCalendar)}
                    className={`shrink-0 px-2 py-0  ${variation ? '' : 'border border-gray-200'}`}
                >
                    <CalendarIcon size={24} />
                </Button>
            </Block>
            {showCalendar && !disabled ? (
                <Block className="absolute left-0 right-0 z-10">
                    <Calendar
                        variation={variation}
                        value={date}
                        onChange={(e) => {
                            setDate(e);
                        }}
                    />
                </Block>
            ) : (
                ''
            )}
        </div>
    );
};
DatePicker.displayName = 'DatePicker';

export default DatePicker;
