import * as React from "react";
import classNames from "classnames";
import {
  AriaDateFieldProps,
  AriaTimeFieldProps,
  DateValue,
  TimeValue,
  useDateField,
  useDateSegment,
  useTimeField,
} from "react-aria";
import { DateFieldState, DateSegment, useDateFieldState, useTimeFieldState } from "react-stately";

import { createCalendar } from "@internationalized/date";

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

interface DateFieldProps<T extends DateValue> extends AriaDateFieldProps<T> {}

export function DateTimeField<T extends DateValue>(props: DateFieldProps<T>) {
  const ref = React.useRef<HTMLDivElement>(null);
  const state = useDateFieldState({ ...props, locale: "en-US", createCalendar });
  const { fieldProps } = useDateField(props, state, ref);

  return (
    <div {...fieldProps} ref={ref}>
      {state.segments.map((segment, i) => (
        <DateTimeSegment key={i} segment={segment} state={state} />
      ))}
    </div>
  );
}

export interface TimeFieldProps<T extends TimeValue> extends AriaTimeFieldProps<T> {}

export function TimeField<T extends TimeValue>(props: TimeFieldProps<T>) {
  const ref = React.useRef<HTMLDivElement>(null);
  const state = useTimeFieldState({ ...props, locale: "en-US" });
  const { labelProps, fieldProps } = useTimeField(props, state, ref);

  return (
    <div className="wrapper">
      <span {...labelProps}>{props.label}</span>
      <div {...fieldProps} ref={ref} className="field">
        {state.segments.map((segment, i) => (
          <DateTimeSegment key={i} segment={segment} state={state} />
        ))}
        {state.validationState === "invalid" && <span aria-hidden="true">🚫</span>}
      </div>
    </div>
  );
}

interface DateTimeSegmentProps {
  segment: DateSegment;
  state: DateFieldState;
}

function DateTimeSegment(props: DateTimeSegmentProps) {
  const { segment, state } = props;

  const ref = React.useRef<HTMLDivElement>(null);
  const { segmentProps } = useDateSegment(segment, state, ref);

  return (
    <span
      {...segmentProps}
      ref={ref}
      className={classNames(styles.segment, { [styles.placeholder]: segment.isPlaceholder })}>
      {segment.text}
    </span>
  );
}
