import type { ComponentProps, ReactNode } from 'react'

import { Field, FieldDescription, FieldLabel } from '@evobgp/ui/components/field'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@evobgp/ui/components/select'
import { cn } from '@evobgp/ui/lib/utils'

export type SelectMenuItem<T extends string = string> = {
  value: T
  label: ReactNode
  disabled?: boolean
}

type SelectRootProps = ComponentProps<typeof Select>

export interface SelectMenuProps<T extends string = string>
  extends Omit<SelectRootProps, 'children' | 'onValueChange' | 'value' | 'defaultValue'> {
  items: ReadonlyArray<SelectMenuItem<T>>
  value?: T | null
  defaultValue?: T | null
  onValueChange?: (value: T | null) => void
  placeholder?: string
  id?: string
  triggerClassName?: string
  contentClassName?: string
  size?: 'sm' | 'default'
  side?: ComponentProps<typeof SelectContent>['side']
}

/** ReUI c-select-4: `items` на Root, опции в `SelectGroup`. */
export function SelectMenu<T extends string = string>({
  items,
  placeholder,
  id,
  triggerClassName,
  contentClassName,
  size = 'default',
  side,
  value,
  defaultValue,
  onValueChange,
  ...selectProps
}: SelectMenuProps<T>) {
  return (
    <Select
      items={items}
      value={value}
      defaultValue={defaultValue}
      onValueChange={(next) => onValueChange?.(next as T | null)}
      {...selectProps}
    >
      <SelectTrigger id={id} className={cn('w-full', triggerClassName)} size={size}>
        <SelectValue placeholder={placeholder} />
      </SelectTrigger>
      <SelectContent side={side} className={contentClassName}>
        <SelectGroup>
          {items.map((item) => (
            <SelectItem key={item.value} value={item.value} disabled={item.disabled}>
              {item.label}
            </SelectItem>
          ))}
        </SelectGroup>
      </SelectContent>
    </Select>
  )
}

export interface SelectFieldProps<T extends string = string> extends SelectMenuProps<T> {
  label?: ReactNode
  description?: ReactNode
  fieldClassName?: string
}

export function SelectField<T extends string = string>({
  label,
  description,
  fieldClassName,
  id,
  ...menuProps
}: SelectFieldProps<T>) {
  return (
    <Field className={fieldClassName}>
      {label ? <FieldLabel htmlFor={id}>{label}</FieldLabel> : null}
      <SelectMenu id={id} {...menuProps} />
      {description ? (
        typeof description === 'string' ? (
          <FieldDescription className="font-mono text-xs">{description}</FieldDescription>
        ) : (
          description
        )
      ) : null}
    </Field>
  )
}
