"use client"

import * as React from "react"
import {
  type Control,
  type FieldPath,
  type FieldValues,
} from "react-hook-form"

import {
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/shared/components/ui/form"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/shared/components/ui/select"

export interface SelectOption {
  value: string
  label: string
}

export interface SelectFieldProps<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> {
  /** react-hook-form control 实例 */
  control: Control<TFieldValues>
  /** 字段路径 */
  name: TName
  /** 标签文本 */
  label: string
  /** 占位符 */
  placeholder?: string
  /** 描述文本 */
  description?: React.ReactNode
  /** 选项列表 */
  options: SelectOption[]
  /** 是否禁用 */
  disabled?: boolean
  /** FormItem 的 className */
  itemClassName?: string
  /** FormLabel 右侧的额外节点（如"新建"按钮） */
  labelSlot?: React.ReactNode
  /**
   * 自定义 value 转换：从 field.value → Select 的 value（string）。
   * 常用于 number 字段：`(v) => String(v)`
   */
  toSelectValue?: (value: unknown) => string
  /**
   * 自定义 onChange 转换：从 Select 的 string value → field.onChange 的值。
   * 常用于 number 字段：`(val) => parseInt(val, 10)`
   */
  fromSelectValue?: (val: string) => unknown
}

/**
 * 通用选择字段组件，封装 FormField + FormItem + FormLabel + Select + SelectContent + SelectItem + FormMessage。
 *
 * 用于替代各表单中重复的 `<FormField render={({ field }) => <Select>...}>` 模式。
 *
 * @example 字符串值
 * <SelectField
 *   control={control}
 *   name="subject"
 *   label="Subject"
 *   placeholder="Select subject"
 *   options={subjects.map(s => ({ value: s.id, label: s.name }))}
 * />
 *
 * @example 数值字段
 * <SelectField
 *   control={control}
 *   name="difficulty"
 *   label="Difficulty"
 *   toSelectValue={(v) => String(v)}
 *   fromSelectValue={(val) => parseInt(val, 10)}
 *   options={[{ value: "1", label: "Easy" }, ...]}
 * />
 */
export function SelectField<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
  control,
  name,
  label,
  placeholder,
  description,
  options,
  disabled,
  itemClassName,
  labelSlot,
  toSelectValue,
  fromSelectValue,
}: SelectFieldProps<TFieldValues, TName>) {
  return (
    <FormField
      control={control}
      name={name}
      render={({ field }) => (
        <FormItem className={itemClassName}>
          <div className="flex items-center justify-between gap-2">
            <FormLabel>{label}</FormLabel>
            {labelSlot}
          </div>
          <Select
            value={toSelectValue ? toSelectValue(field.value) : (field.value as string)}
            onValueChange={fromSelectValue ? (val) => field.onChange(fromSelectValue(val)) : field.onChange}
            disabled={disabled}
          >
            <FormControl>
              <SelectTrigger>
                <SelectValue placeholder={placeholder} />
              </SelectTrigger>
            </FormControl>
            <SelectContent>
              {options.map((opt) => (
                <SelectItem key={opt.value} value={opt.value}>
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          {description ? <FormDescription>{description}</FormDescription> : null}
          <FormMessage />
        </FormItem>
      )}
    />
  )
}
