/** @jsxRuntime classic */
/** @jsx jsx */
import React, { FC, useState, useRef, useEffect } from 'react';
import { IIcons } from '../../types/theme';
import cx from 'classnames';
import { jsx, Theme, useTheme } from '@emotion/react';
import { StyledInput, DeleteButtonStyle, InputContainer } from './style';
import { getIcon, BnRemove } from '../../icons';
import { capitalize } from '../../functions';
import { Tooltip } from '../Tooltip';
import { Popup } from '../Popup';
import dayjs, { Dayjs } from 'dayjs';
import { ErrorMessage } from '../ErrorMessage';
import { Date } from '../DateInput/comp/Date';
import { DateInputProps } from '../../types';
import { DateOfBirth } from '../DateInput/comp/DateOfBirth';

export const DateInput: FC<
  DateInputProps & React.InputHTMLAttributes<HTMLInputElement>
> = ({
  leftIcon = '',
  rightIcon = '',
  children,
  sizer = 'S',
  noLabel = false,
  label = '',
  info = '',
  helper = '',
  helperContent = '',
  notBefore = '',
  enablePast = false,
  isBirthday = false,
  error = undefined,
  hideError = false,
  disableTrailing = true,
  setChange = () => {},
  clear = () => {},
  // colors = ThemeColors,
  ...rest
}) => {
  const [isFocus, setFocus] = useState<boolean>(false);
  const [innerValue, setInnerValue] = useState<string>('');
  const [isHover, setHover] = useState<boolean>(false);
  const [visited, setVisited] = useState<boolean>(false);
  const inputRef = useRef(null);
  const colors = useTheme();
  // const { colors: ThemeC } = useColors();
  const [selectedDate, setSelectedDate] = useState<Dayjs>();
  const [value, setValue] = useState('');
  const [isDateOpen, setDateOpen] = useState<boolean>(false);

  const checkPastDates = (day: Dayjs) => {
    if (enablePast) {
      return notBefore
        ? day.isBefore(dayjs(dayjs(notBefore).format('YYYY-MM-DD')))
        : false;
    } else {
      return notBefore
        ? day.isBefore(dayjs(dayjs(notBefore).format('YYYY-MM-DD')))
        : day.isBefore(dayjs(dayjs().format('YYYY-MM-DD')));
    }
  };

  useEffect(() => {
    if (
      value !== dayjs(rest.value as string).format('YYYY-MM-DD') &&
      rest.value
    ) {
      handleChange(dayjs(rest.value as string));
    } else {
      if (!rest.value) {
        setInnerValue('');
        // setSelectedDate(null);
        setValue('');
      }
    }
  }, [rest.value]);

  useEffect(() => {
    selectedDate && setChange?.(selectedDate.format('YYYY-MM-DD'));
  }, [selectedDate]);

  const handleChange = (val: Dayjs) => {
    if (val) {
      setValue(val.format('MMM DD, YYYY'));
      setInnerValue(val.format('MMM DD, YYYY'));
      setSelectedDate(val);
      //@ts-ignore
      if (inputRef && inputRef.current) {
        //@ts-ignore
        inputRef.current.focus();
      }
      setDateOpen(false);
      //@ts-ignore
      if (rest.onChange) {
        //@ts-ignore
        rest.onChange(dayjs(val.format('MM/DD/YYYY')).format('YYYY-MM-DD'));
      }
    }
  };

  return (
    <InputContainer
      className={cx({
        M: sizer === 'M',
        S: sizer === 'S',
      })}
      theme={{ ...colors }}
      style={{ ...rest.style }}
    >
      {(label || noLabel) && (
        <div className="label">
          <div>
            {capitalize(label)}
            {rest.required && ' *'}
          </div>
          {info && <Tooltip content={info}>{getIcon('info', 'l')}</Tooltip>}
        </div>
      )}
      <Popup
        placement="bottom-start"
        padding={0}
        disableAutoTrigger
        // fullWidth
        body={
          isBirthday ? (
            <DateOfBirth
              defaultValue={selectedDate}
              disabledDates={checkPastDates}
              onChange={handleChange}
            />
          ) : (
            <Date
              defaultValue={selectedDate}
              disabledDates={checkPastDates}
              onChange={handleChange}
            />
          )
        }
        onOpenChange={setDateOpen}
        trigger={isDateOpen}
      >
        <StyledInput
          theme={{ ...colors }}
          className={cx({
            focus: isFocus,
            error: error && visited,
            hover: isHover,
            M: sizer === 'M',
            S: sizer === 'S',
          })}
          onClick={() => {
            if (inputRef.current) {
              //@ts-ignore
              inputRef.current.focus();
            }
          }}
          onMouseEnter={() => {
            setHover(true);
          }}
          onMouseLeave={() => {
            setHover(false);
          }}
        >
          {leftIcon && getIcon(leftIcon, 'r')}
          <input
            ref={inputRef}
            {...rest}
            value={innerValue}
            onChange={(e) => {
              setInnerValue(e.target.value);
              if (!e.target.value) {
                if (rest.onChange) {
                  rest.onChange(e);
                }
              }
            }}
            onFocus={(e) => {
              setFocus(true);
              setDateOpen(true);
              if (rest.onFocus) {
                rest.onFocus(e);
              }
            }}
            onBlur={(e) => {
              setFocus(false);
              setVisited(true);
              if (rest.onBlur) {
                rest.onBlur(e);
              }
              if (dayjs(innerValue).isValid()) {
                if (innerValue !== value) {
                  handleChange(dayjs(innerValue));
                }
              } else {
                if (innerValue) {
                  setInnerValue('');
                  setValue('');
                  setSelectedDate(dayjs());
                  //@ts-ignore
                  if (rest.onChange) {
                    //@ts-ignore
                    rest.onChange(undefined);
                  }
                }
              }
            }}
          />
          {!disableTrailing && innerValue.length > 0 && isHover && (
            <DeleteButton
              onClick={() => {
                if (inputRef && inputRef.current) {
                  // @ts-ignore: Object is possibly 'null'.
                  inputRef.current.focus();
                }
                setInnerValue('');
                if (clear) {
                  clear();
                }
              }}
              theme={{ ...colors }}
            />
          )}
          {rightIcon && getIcon(rightIcon, 'l')}
        </StyledInput>
      </Popup>
      {!hideError && (
        <div className="error-message" style={{ minHeight: '15px' }}>
          {visited && <ErrorMessage error={error || ''} />}
        </div>
      )}
      {helper && (
        <div className="helper">
          {helperContent && (
            <Tooltip content={helperContent}>{getIcon('info', 'r')}</Tooltip>
          )}
          <div>{capitalize(helper)}</div>
        </div>
      )}
    </InputContainer>
  );
};

interface DeleteButtonProps {
  theme: Theme;
  onClick: () => void;
}
const DeleteButton = ({ theme, onClick }: DeleteButtonProps) => {
  return (
    <DeleteButtonStyle theme={theme} onClick={onClick}>
      <BnRemove />
    </DeleteButtonStyle>
  );
};
