'use client';

import React from 'react';
import { useFormContext } from './context';
import type { FormItemProps } from './types';

export const FormItem = <
  TValues extends Record<string, any> = Record<string, any>,
>(
  props: FormItemProps<TValues>
) => {
  const {
    name,
    render,
    trigger: triggerType = 'onChange',
    disabled = false,
    rules = [],
  } = props;

  const {
    getFieldValue,
    setFieldValue,
    getFieldError,
    validateField,
    registerFieldRules,
    subscribe,
  } = useFormContext<TValues>();

  // 使用 useState 管理字段值和错误状态
  const [fieldValue, setLocalFieldValue] = React.useState(() =>
    getFieldValue(name)
  );
  const [error, setLocalError] = React.useState(() => getFieldError(name));

  // 使用 ref 存储最新的函数引用，避免订阅回调中的闭包问题
  const getFieldValueRef = React.useRef(getFieldValue);
  const getFieldErrorRef = React.useRef(getFieldError);

  React.useEffect(() => {
    getFieldValueRef.current = getFieldValue;
    getFieldErrorRef.current = getFieldError;
  }, [getFieldValue, getFieldError]);

  // 使用 useEffect 订阅字段变化
  React.useEffect(() => {
    const unsubscribe = subscribe(name, () => {
      // 当字段变化时，更新状态（使用 ref 获取最新值）
      const newValue = getFieldValueRef.current(name);
      const newError = getFieldErrorRef.current(name);

      setLocalFieldValue((prev: any) => (prev !== newValue ? newValue : prev));
      setLocalError((prev: string | undefined) =>
        prev !== newError ? newError : prev
      );
    });

    return unsubscribe;
  }, [name, subscribe]);

  // 注册字段规则
  React.useEffect(() => {
    if (rules.length > 0) {
      registerFieldRules(name, rules);
    }
  }, [name, rules, registerFieldRules]);

  // onChange 处理
  const handleChange = React.useCallback(
    (value: any) => {
      setFieldValue(name, value);

      // 根据 trigger 类型决定是否立即校验
      if (triggerType === 'onChange') {
        validateField(name);
      }
    },
    [name, setFieldValue, triggerType, validateField]
  );

  // onBlur 处理
  const handleBlur = React.useCallback(() => {
    // 如果设置为 onBlur 校验，失去焦点时触发校验
    if (triggerType === 'onBlur') {
      validateField(name);
    }
  }, [triggerType, name, validateField]);

  return (
    <>
      {render(
        {
          value: fieldValue,
          onChange: handleChange,
          onBlur: handleBlur,
        },
        error
      )}
    </>
  );
};
