import * as React from "react";
import classNames from "classnames";
import { AriaDatePickerProps, DateValue, useDatePicker } from "react-aria";
import { useDatePickerState } from "react-stately";

import { Calendar as CalendarIcon } from "@faulty/gdq-icons/icons/Calendar";

import { Card } from "../Card/Card";
import { Clickable } from "../Clickable/Clickable";
import { Control, ControlInputProps } from "../Control/Control";
import { InputAttachmentProps, InputWithAttachments, useInputStyleClasses } from "../Input/Input";
import { useInteractiveClass } from "../Interactive/Interactive";
import { Stack } from "../Stack/Stack";
import { Calendar } from "./Calendar";
import { DateTimeField } from "./DateTimeField";
import { PickerPopover } from "./PickerPopover";

import styles from "./DatePicker.module.css";

export interface DatePickerProps<T extends DateValue>
  extends AriaDatePickerProps<T>,
    ControlInputProps,
    InputAttachmentProps {
  // TODO: Not sure of the best way to inherent these props directly
  /**
   * Determines whether the date picker popover should close automatically when a date is selected.
   * @default true
   */
  shouldCloseOnSelect?: boolean | (() => boolean);
}

export function DatePicker<T extends DateValue>(props: DatePickerProps<T>) {
  const inputStyles = useInputStyleClasses(props);

  const ref = React.useRef<HTMLDivElement>(null);
  const state = useDatePickerState(props);
  const {
    buttonProps,
    calendarProps,
    dialogProps,
    labelProps,
    descriptionProps,
    fieldProps,
    errorMessageProps,
    groupProps,
  } = useDatePicker(props, state, ref);

  const interactiveClass = useInteractiveClass({ background: true });

  return (
    <Control
      {...props}
      labelProps={labelProps}
      descriptionProps={descriptionProps}
      errorMessageProps={errorMessageProps}>
      <InputWithAttachments {...props}>
        <Stack asChild direction="horizontal" justify="space-between" align="center">
          <div
            {...groupProps}
            ref={ref}
            className={classNames(styles.container, inputStyles.inputPadding)}>
            <DateTimeField {...fieldProps} />
            <Clickable
              {...buttonProps}
              className={classNames(styles.triggerButton, interactiveClass)}>
              <CalendarIcon style={{ display: "block" }} size={20} />
            </Clickable>
          </div>
        </Stack>
      </InputWithAttachments>
      {state.isOpen ? (
        <PickerPopover
          state={state}
          triggerRef={ref}
          placement="bottom start"
          dialogProps={dialogProps}>
          <Card floating>
            <Calendar {...calendarProps} />
          </Card>
        </PickerPopover>
      ) : null}
    </Control>
  );
}
