import { css } from 'glamor';
import { observer } from 'mobx-react';
import React, { useState } from 'react';
import { useLocalStyles } from '../../styles/defaults/useLocalStyles';
import { InputWrapper } from '../input/InputWrapper';
import { InputComponentStyles } from '../input/input.styles.interface';
import { getComponentInputStyles } from '../input/input.component.styles';
import { useApphouse } from '../../context/useApphouse';
import { isValidDate } from '../../utils/string/isValidDate';
import { InputProps } from '../input/input.interface';

interface DatePickerProps
  extends Pick<
    InputProps,
    | 'variant'
    | 'label'
    | 'id'
    | 'required'
    | 'disabled'
    | 'description'
    | 'styleOverwrites'
  > {
  onDateSelect: (date: string) => void;
  /**
   * A string representing the date entered in the input.
   * The date is formatted according to Date strings format.
   * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Date_and_time_formats#date_strings
   * @default undefined
   * @optional
   */
  value?: string;
  /**
   * The minimum date that the user can select.
   * @default undefined user can select any date
   */
  min?: string;
  /**
   * The maximum date that the user can select.
   * @default undefined user can select any date
   */
  max?: string;
  /**
   * The name of the input.
   */
  name?: string;
  /**
   * The width of the input.
   * @default undefined
   * @optional
   */
  width?: string | number;
}

/**
 * A wrapper on the input date element.
 * It augments the input with a label and description.
 * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date
 * Date format: June 7, 2005
 * const dateString = '2005-06-07';
 *
 * Time format: 8:45 AM
 * const timeString1 = '08:45';
 *
 * Time format with seconds: 8:45 AM and 25 seconds
 * const timeString2 = '08:45:25';
 *
 * Time format with date and time: 3:40 AM on August 4, 33
 * const dateTimeString1 = '0033-08-04T03:40';
 *
 * Time format with date, time, and seconds: 30 seconds after 2:00 PM on April 1, 1977
 * const dateTimeString2 = '1977-04-01T14:00:30';
 *
 * Time format with UTC: Midnight UTC on January 1, 1901
 * const dateTimeString3 = '1901-01-01T00:00Z';
 *
 * Time format with timezone offset: 1 second past midnight Eastern Standard Time (EST) on January 1, 1901
 * const dateTimeString4 = '1901-01-01T00:00:01-04:00';
 */
export const DatePicker: React.FC<DatePickerProps> = observer(
  ({
    onDateSelect,
    variant = 'm',
    styleOverwrites,
    label,
    id,
    width,
    required,
    value,
    disabled = false,
    description
  }) => {
    const { theme } = useApphouse();
    const { colors } = theme;
    const [selectedDate, setSelectedDate] = useState<string | undefined>(value);

    const handleDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
      try {
        const date = event.target.value;
        setSelectedDate(date);
        onDateSelect(date);
      } catch (error) {
        console.error(error);
      }
    };

    const componentStyles: InputComponentStyles = getComponentInputStyles(
      theme,
      variant
    );

    const localStyles = useLocalStyles(componentStyles, styleOverwrites);
    const hasInvalidDate =
      selectedDate !== undefined && !isValidDate(selectedDate);

    const datePickerIconColorStyle = {
      '::-webkit-calendar-picker-indicator': {
        backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" viewBox="0 0 24 24"><path fill="${colors.brand}" d="M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z"/></svg>')`
      }
    };
    return (
      <InputWrapper
        variant={variant}
        label={label}
        id={id}
        disabled={disabled}
        required={required}
        styleOverwrites={localStyles}
        description={description}
        error={hasInvalidDate ? 'Invalid Date' : undefined}
        width={width}
      >
        <input
          type="date"
          value={value}
          onChange={handleDateChange}
          width={width}
          {...css(localStyles.input, datePickerIconColorStyle)}
        />
      </InputWrapper>
    );
  }
);
