'use client'

import * as React from 'react'
import {
  Select,
  SelectTrigger,
  SelectContent,
  SelectItem,
  SelectValue,
  type SelectIcon,
  type SelectSize,
} from './Select'

export type SimpleSelectOption<OptionType> = {
  label: string
  value: OptionType
  Icon?: SelectIcon
}

type SharedProps<OptionType> = {
  /** Options to display in the dropdown. */
  options: SimpleSelectOption<OptionType>[]
  /** Placeholder text shown when no option is selected. */
  placeholder?: string
  /** Disables the select and prevents user interaction. */
  disabled?: boolean
  /** Additional CSS class names applied to the trigger. */
  className?: string
  /** Called with the new value when the selection changes. */
  onValueChange?: (newValue: OptionType) => void
  /** Whether the dropdown is open on first render. */
  defaultOpen?: boolean
  /** Visual density of the trigger and items. Defaults to `'default'`. */
  size?: SelectSize
  /** When false, the hover clear control is not shown (default true). */
  clearable?: boolean
}

/**
 * Controlled mode: pass `value` and manage selection state in the parent.
 * `defaultValue` is disallowed when using controlled mode.
 */
interface ControlledProps<OptionType> extends SharedProps<OptionType> {
  /** The currently selected value, managed by the parent. */
  value: string
  defaultValue?: never
}

/**
 * Uncontrolled mode: optionally pass `defaultValue` for an initial selection.
 * The component manages its own state after mount.
 * `value` is disallowed when using uncontrolled mode.
 */
interface UncontrolledProps<OptionType> extends SharedProps<OptionType> {
  value?: never
  /** The initially selected value. The component manages state after mount. */
  defaultValue?: string
}

export type SimpleSelectProps<OptionType extends string = string> =
  | ControlledProps<OptionType>
  | UncontrolledProps<OptionType>

/**
 * Opinionated select built on the Select primitive. Pass an `options` array and
 * get a fully composed select with no manual subcomponent setup. Supports
 * controlled (`value` + `onValueChange`) and uncontrolled (`defaultValue`) usage.
 */
export function SimpleSelect<OptionType extends string = string>({
  options,
  value,
  onValueChange,
  defaultValue,
  placeholder,
  disabled,
  defaultOpen,
  className,
  size = 'default',
  clearable = true,
}: SimpleSelectProps<OptionType>) {
  // **Uncontrolled** local state:
  const [internalValue, setInternalValue] = React.useState<string | undefined>(
    defaultValue,
  )

  // Determine if we are in controlled mode (i.e., `value` prop is present)
  const isControlled = value !== undefined

  // The actual value to pass to <Select>
  const finalValue = isControlled ? value : internalValue

  // Unified handler:
  // - If controlled, we just call `onValueChange`.
  // - If uncontrolled, we also update the local `internalValue`.
  const handleValueChange = React.useCallback(
    (newVal: OptionType) => {
      if (!isControlled) {
        setInternalValue(newVal)
      }
      onValueChange?.(newVal)
    },
    [isControlled, onValueChange],
  )

  return (
    <Select
      value={finalValue}
      onValueChange={handleValueChange}
      disabled={disabled}
      defaultOpen={defaultOpen}
      size={size}
      clearable={clearable}
    >
      <SelectTrigger className={className}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>

      <SelectContent>
        {options.map(({ value, Icon, label }) => (
          <SelectItem key={value} Icon={Icon} value={value}>
            {label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  )
}
