"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 { Input } from "@/shared/components/ui/input"

export interface TextFieldProps<
  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
  /** Input 类型，默认 "text" */
  type?: "text" | "number" | "password" | "email" | "datetime-local" | "tel" | "url"
  /** 是否禁用 */
  disabled?: boolean
  /** FormItem 的 className（用于布局，如 "col-span-2"） */
  itemClassName?: string
  /** Input 的额外 className */
  inputClassName?: string
  /** 透传到 Input 的其他 props（如 min/max/step） */
  inputProps?: Omit<
    React.InputHTMLAttributes<HTMLInputElement>,
    "name" | "value" | "onChange" | "onBlur" | "disabled" | "type" | "placeholder" | "className"
  >
  /**
   * 自定义 value 转换：从 field.value → input value。
   * 常用于 number 字段处理 null/undefined → ""。
   */
  toInputValue?: (value: unknown) => string | number | readonly string[]
  /**
   * 自定义 onChange 转换：从 input event → field.onChange 的值。
   * 常用于 number 字段处理空字符串 → null。
   */
  fromInputValue?: (e: React.ChangeEvent<HTMLInputElement>) => unknown
}

/**
 * 通用文本字段组件，封装 FormField + FormItem + FormLabel + FormControl + Input + FormMessage。
 *
 * 用于替代各表单中重复的 `<FormField render={({ field }) => <Input {...field} />}>` 模式。
 *
 * @example
 * <TextField control={control} name="title" label="Title" placeholder="..." />
 *
 * @example 数值字段
 * <TextField
 *   control={control}
 *   name="totalScore"
 *   label="Total Score"
 *   type="number"
 * />
 */
export function TextField<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
  control,
  name,
  label,
  placeholder,
  description,
  type = "text",
  disabled,
  itemClassName,
  inputClassName,
  inputProps,
  toInputValue,
  fromInputValue,
}: TextFieldProps<TFieldValues, TName>) {
  return (
    <FormField
      control={control}
      name={name}
      render={({ field }) => (
        <FormItem className={itemClassName}>
          <FormLabel>{label}</FormLabel>
          <FormControl>
            <Input
              type={type}
              placeholder={placeholder}
              disabled={disabled}
              className={inputClassName}
              {...inputProps}
              {...field}
              value={toInputValue ? toInputValue(field.value) : (field.value ?? "")}
              onChange={fromInputValue ? fromInputValue : field.onChange}
            />
          </FormControl>
          {description ? <FormDescription>{description}</FormDescription> : null}
          <FormMessage />
        </FormItem>
      )}
    />
  )
}
