'use client';
import { createCalendar } from '@internationalized/date';
import { useDateSegment, useDisplayNames, useDateField, useTimeField } from '@react-aria/datepicker';
import { useDateFormatter, useLocale } from '@react-aria/i18n';
import { useDateFieldState, useTimeFieldState } from '@react-stately/datepicker';
import React, { forwardRef, useRef, useMemo, useImperativeHandle } from 'react';
import { useProviderProps } from '@keystar/ui/core';
import { FieldPrimitive } from '@keystar/ui/field';
import { mergeProps, mergeRefs } from '@react-aria/utils';
import { useFocusRing, createFocusManager } from '@react-aria/focus';
import { css, classNames, tokenSchema } from '@keystar/ui/style';
import { toDataAttributes } from '@keystar/ui/utils';
import { jsx, jsxs } from 'react/jsx-runtime';
import { Text } from '@keystar/ui/typography';

const Input = /*#__PURE__*/forwardRef(function Input(props, ref) {
  let inputRef = useRef(null);
  let {
    children,
    className,
    disableFocusRing,
    fieldProps,
    inputClassName,
    isDisabled,
    style,
    validationState
  } = props;
  let {
    focusProps,
    isFocusVisible,
    isFocused
  } = useFocusRing({
    isTextInput: true,
    within: true
  });
  let isInvalid = validationState === 'invalid' && !isDisabled;
  let inputStyles = useInputStyles(inputClassName, {
    isDisabled,
    isInvalid,
    isFocused,
    isFocusVisible: isFocusVisible && !disableFocusRing
  });
  return /*#__PURE__*/jsx("div", {
    role: "presentation",
    ...mergeProps(fieldProps, focusProps),
    className: className,
    style: style,
    children: /*#__PURE__*/jsx("div", {
      role: "presentation",
      ...inputStyles,
      children: /*#__PURE__*/jsx("div", {
        role: "presentation",
        className: css({
          alignItems: 'center',
          display: 'flex',
          height: '100%',
          overflowX: 'auto',
          scrollbarWidth: 'none',
          msOverflowStyle: 'none'
        }),
        ref: mergeRefs(ref, inputRef),
        children: children
      })
    })
  });
});
function useInputStyles(inputClassName, state) {
  let {
    isDisabled,
    isInvalid,
    isFocused,
    isFocusVisible
  } = state;
  let className = classNames(inputClassName, css({
    backgroundColor: tokenSchema.color.background.canvas,
    border: `${tokenSchema.size.border.regular} solid ${tokenSchema.color.alias.borderIdle}`,
    borderRadius: tokenSchema.size.radius.regular,
    height: tokenSchema.size.element.regular,
    lineHeight: tokenSchema.typography.lineheight.small,
    outline: 0,
    overflow: 'visible',
    paddingBlock: tokenSchema.size.space.small,
    paddingInline: tokenSchema.size.space.medium,
    position: 'relative',
    textIndent: 0,
    verticalAlign: 'top',
    minWidth: tokenSchema.size.scale[2000],
    width: '100%',
    '&[data-invalid=true]': {
      borderColor: tokenSchema.color.alias.borderInvalid
    },
    '&[data-focus]': {
      borderColor: tokenSchema.color.alias.borderFocused,
      boxShadow: `0 0 0 1px ${tokenSchema.color.alias.borderFocused}`
    },
    '&[data-disabled=true]': {
      backgroundColor: tokenSchema.color.background.surfaceSecondary,
      borderColor: 'transparent'
    }
  }));
  return {
    ...toDataAttributes({
      disabled: isDisabled || undefined,
      invalid: isInvalid || undefined,
      focus: isFocusVisible ? 'visible' : isFocused || undefined
    }),
    className
  };
}

function InputSegment(_ref) {
  let {
    segment,
    state,
    ...otherProps
  } = _ref;
  if (segment.type === 'literal') {
    return /*#__PURE__*/jsx(LiteralSegment, {
      segment: segment
    });
  }
  return /*#__PURE__*/jsx(EditableSegment, {
    segment: segment,
    state: state,
    ...otherProps
  });
}

/** A separator, e.g. punctuation like "/" or "." */
function LiteralSegment(_ref2) {
  let {
    segment
  } = _ref2;
  return /*#__PURE__*/jsx(Text, {
    elementType: "span",
    "aria-hidden": "true",
    color: "neutralTertiary",
    trim: false,
    UNSAFE_className: css({
      userSelect: 'none',
      whiteSpace: 'pre'
    }),
    "data-testid": segment.type === 'literal' ? undefined : segment.type,
    children: segment.text
  });
}
function EditableSegment(_ref3) {
  let {
    segment,
    state
  } = _ref3;
  let ref = useRef(null);
  let {
    segmentProps
  } = useDateSegment(segment, state, ref);
  return /*#__PURE__*/jsxs("div", {
    ...segmentProps,
    ...toDataAttributes({
      placeholder: segment.isPlaceholder,
      readonly: !segment.isEditable
    }),
    ref: ref,
    className: css({
      borderRadius: tokenSchema.size.radius.small,
      color: tokenSchema.color.foreground.neutral,
      paddingInline: tokenSchema.size.space.xsmall,
      // text styles
      fontFamily: tokenSchema.typography.fontFamily.base,
      fontSize: tokenSchema.typography.text.regular.size,
      fontVariantNumeric: 'tabular-nums',
      fontWeight: tokenSchema.typography.fontWeight.regular,
      lineHeight: tokenSchema.typography.lineheight.small,
      whiteSpace: 'nowrap',
      MozOsxFontSmoothing: 'auto',
      WebkitFontSmoothing: 'auto',
      '[dir=ltr] &': {
        textAlign: 'right'
      },
      '[dir=rtl] &': {
        textAlign: 'left'
      },
      '&[data-placeholder=true]': {
        color: tokenSchema.color.foreground.neutralTertiary
      },
      '&:focus': {
        backgroundColor: tokenSchema.color.background.accentEmphasis,
        color: tokenSchema.color.foreground.onEmphasis,
        outline: 'none'
      }
    }),
    style: {
      ...segmentProps.style,
      minWidth: segment.maxValue != null ? String(segment.maxValue).length + 'ch' : undefined
    },
    "data-testid": segment.type,
    children: [/*#__PURE__*/jsx("span", {
      "aria-hidden": "true",
      "data-hidden": !segment.isPlaceholder,
      className: css({
        display: 'block',
        fontStyle: 'italic',
        height: '0',
        pointerEvents: 'none',
        textAlign: 'center',
        visibility: 'hidden',
        width: '100%',
        '&[data-hidden=false]': {
          height: 'auto',
          visibility: 'visible'
        }
      }),
      children: segment.placeholder
    }), !segment.isPlaceholder && segment.text]
  });
}

function useFormatHelpText(props) {
  let formatter = useDateFormatter({
    dateStyle: 'short'
  });
  let displayNames = useDisplayNames();
  return useMemo(() => {
    if (props.description) {
      return props.description;
    }
    if (props.showFormatHelpText) {
      return formatter.formatToParts(new Date()).map(s => {
        if (s.type === 'literal') {
          return s.value;
        }

        // @ts-expect-error - not sure what's going on here
        return displayNames.of(s.type);
      }).join(' ');
    }
    return '';
  }, [props.description, props.showFormatHelpText, formatter, displayNames]);
}
function useFocusManagerRef(ref) {
  let domRef = useRef(null);
  // @ts-expect-error - useImperativeHandle wants all properties from `ref`, wtf???
  useImperativeHandle(ref, () => ({
    focus() {
      createFocusManager(domRef).focusFirst({
        tabbable: true
      });
    }
  }));
  return domRef;
}

function DateField(props, ref) {
  props = useProviderProps(props);
  let {
    autoFocus,
    isDisabled,
    isReadOnly,
    isRequired
  } = props;
  let domRef = useFocusManagerRef(ref);
  let {
    locale
  } = useLocale();
  let state = useDateFieldState({
    ...props,
    locale,
    createCalendar
  });
  let inputRef = useRef(null);
  let {
    labelProps,
    fieldProps,
    descriptionProps,
    errorMessageProps
  } = useDateField(props, state, inputRef);

  // Note: this description is intentionally not passed to useDatePicker.
  // The format help text is unnecessary for screen reader users because each segment already has a label.
  let description = useFormatHelpText(props);
  if (description && !props.description) {
    descriptionProps.id = undefined;
  }
  if (props.errorMessage) {
    state.validationState = 'invalid';
  }
  return /*#__PURE__*/jsx(FieldPrimitive, {
    ...props,
    ref: domRef,
    description: description,
    labelProps: labelProps,
    descriptionProps: descriptionProps,
    errorMessageProps: errorMessageProps
    // validationState={state.validationState}
    ,
    children: /*#__PURE__*/jsx(Input, {
      ref: inputRef,
      fieldProps: fieldProps,
      isDisabled: isDisabled,
      autoFocus: autoFocus,
      validationState: state.validationState,
      children: state.segments.map((segment, i) => /*#__PURE__*/jsx(InputSegment, {
        segment: segment,
        state: state,
        isDisabled: isDisabled,
        isReadOnly: isReadOnly,
        isRequired: isRequired
      }, i))
    })
  });
}

// forwardRef doesn't support generic parameters, so cast the result to the correct type
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref

/**
 * DateFields allow users to enter and edit date and time values using a keyboard.
 * Each part of a date value is displayed in an individually editable segment.
 */
const _DateField = /*#__PURE__*/React.forwardRef(DateField);

function TimeField(props, ref) {
  props = useProviderProps(props);
  let {
    autoFocus,
    isDisabled,
    isReadOnly,
    isRequired
  } = props;
  let domRef = useFocusManagerRef(ref);
  let {
    locale
  } = useLocale();
  let state = useTimeFieldState({
    ...props,
    locale
  });
  let inputRef = useRef(null);
  let {
    labelProps,
    fieldProps,
    descriptionProps,
    errorMessageProps
  } = useTimeField(props, state, inputRef);
  if (props.errorMessage) {
    state.validationState = 'invalid';
  }
  return /*#__PURE__*/jsx(FieldPrimitive, {
    ...props,
    ref: domRef,
    labelProps: labelProps,
    descriptionProps: descriptionProps,
    errorMessageProps: errorMessageProps
    // validationState={state.validationState}
    ,
    children: /*#__PURE__*/jsx(Input, {
      ref: inputRef,
      fieldProps: fieldProps,
      isDisabled: isDisabled,
      autoFocus: autoFocus,
      validationState: state.validationState,
      children: state.segments.map((segment, i) => /*#__PURE__*/jsx(InputSegment, {
        segment: segment,
        state: state,
        isDisabled: isDisabled,
        isReadOnly: isReadOnly,
        isRequired: isRequired
      }, i))
    })
  });
}

// forwardRef doesn't support generic parameters, so cast the result to the correct type
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref

/**
 * TimeFields allow users to enter and edit time values using a keyboard.
 * Each part of the time is displayed in an individually editable segment.
 */
const _TimeField = /*#__PURE__*/React.forwardRef(TimeField);

export { _DateField as DateField, _TimeField as TimeField };
