import type { ChangeEvent, FocusEvent, InputHTMLAttributes, ReactNode } from 'react'
import { TPktInputSize } from 'shared-types/size'
import type { ITimepickerStrings } from 'shared-types/timepicker'

/**
 * Props for {@link PktTimepicker}: a React time picker with `HH:MM`, aligned with Elements `pkt-timepicker`.
 *
 * The value is submitted via a hidden `input type="time"`; hour/minute fields are the editing UI. Use `value`
 * or `defaultValue` for controlled vs. uncontrolled mode.
 */
export interface IPktTimepicker extends Omit<
  InputHTMLAttributes<HTMLInputElement>,
  'value' | 'onChange' | 'onInput' | 'min' | 'max' | 'step' | 'onFocus' | 'onBlur'
> {
  /** Unique id; used for hour, minute, popup, and hidden input ids. */
  id: string

  /** Visible label (InputWrapper). */
  label: string

  /** Controlled value (`HH:MM`). */
  value?: string

  /** Initial value when the component is uncontrolled. */
  defaultValue?: string

  /**
   * Earliest valid time (`HH:MM`). May be a number or string (HTML attribute / RHF).
   * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time}
   */
  min?: string | number

  /**
   * Latest valid time (`HH:MM`). May be a number or string (HTML attribute / RHF).
   */
  max?: string | number

  /**
   * Step in **seconds** (e.g. `60` = 1 min, `300` = 5 min). Must be a valid multiple (same rules as Elements).
   * @default 60
   */
  step?: number

  /** Hides the clock button and popup; shows a static clock icon. */
  hidePicker?: boolean

  /** Shows previous/next step buttons instead of the popup. */
  stepArrows?: boolean

  /** Full width (`pkt-timepicker--fullwidth`). */
  fullwidth?: boolean

  /** Form field name on the hidden `input`; falls back to `id` if omitted. */
  name?: string

  /** Help text above the field. */
  helptext?: string | ReactNode

  /** Expandable help text (dropdown). */
  helptextDropdown?: string | ReactNode

  /** Button label for expandable help text. */
  helptextDropdownButton?: string

  /** Forces error state on the wrapper. */
  hasError?: boolean

  /** Error message below the field. */
  errorMessage?: string | ReactNode

  /** Shows an "optional" tag. */
  optionalTag?: boolean

  /** Label text for the optional tag. */
  optionalText?: string

  /** Shows a "required" tag. */
  requiredTag?: boolean

  /** Label text for the required tag. */
  requiredText?: string

  /** Extra tag next to the label. */
  tagText?: string | null

  /** Inline layout in InputWrapper. */
  inline?: boolean

  /** Show visible label and help text (`false` = screen-reader-only label). */
  useWrapper?: boolean

  /** Passed through to InputWrapper as `aria-describedby`. */
  ariaDescribedby?: string

  /** Copy for hours, minutes, buttons, and popup. */
  strings?: ITimepickerStrings

  /** Change event from the hidden input (`e.target.value` is `HH:MM`). In React, `onChange` already fires on input. */
  onChange?: (e: ChangeEvent<HTMLInputElement>) => void

  /** Callback with the committed `HH:MM` string. */
  onValueChange?: (value: string) => void

  /**
   * Fires when focus enters this control from outside (not when moving only between hour and minute).
   * Implemented on the root wrapper; spinbuttons must allow focus to bubble so this runs.
   */
  onFocus?: (e: FocusEvent<Element>) => void

  /** Focus leaves the whole component. */
  onBlur?: (e: FocusEvent<Element>) => void

  /** Extra class names on the root (`pkt-timepicker`). */
  className?: string

  /** Size of the Timepicker component. */
  inputSize?: TPktInputSize
}
