/**
 * 表单渲染器组件（运行时）
 * 用于真实业务场景的表单渲染和提交
 * 
 * 特点：
 * - ✅ 支持所有表单字段类型
 * - ✅ 支持验证规则和联动规则  
 * - ✅ 支持动态数据源（API、预定义）
 * - ✅ 非受控组件，内部管理状态
 * - ✅ 支持生命周期钩子（beforeSubmit/afterSubmit/onError）
 * - ✅ 用于生产环境的真实表单提交
 * - ✅ 支持内置按钮和外部按钮两种模式
 * 
 * @example
 * ```tsx
 * // 方式1: 使用内置按钮（简单场景）
 * <FormRenderer 
 *   schema={schema}
 *   onSubmit={handleSubmit}
 *   showSubmit={true}
 *   showCancel={true}
 *   submitText="保存"
 *   cancelText="取消"
 * />
 * 
 * // 方式2: 使用外部按钮（复杂场景，如 Modal）
 * const formRef = useRef<FormRendererRef>(null);
 * 
 * <Modal
 *   footer={
 *     <>
 *       <Button onClick={() => formRef.current?.reset()}>重置</Button>
 *       <Button type="primary" onClick={() => formRef.current?.submit()}>提交</Button>
 *     </>
 *   }
 * >
 *   <FormRenderer 
 *     ref={formRef}
 *     schema={schema}
 *     onSubmit={handleSubmit}
 *   />
 * </Modal>
 * ```
 */

import React, { useImperativeHandle, forwardRef } from 'react';
import { Form, message, Button } from 'antd';
import type { FieldConfig, FormConfig, FormSchema } from './types';
import type { ComponentMeta } from './config';
import { COMPONENT_LIST } from './config';
import { ComponentsContext } from './Designer';
import { useFormCore } from './hooks/useFormCore';
import { computeFormLayout } from './utils/formLayoutHelper';
import { transformToNestedObject, transformToFlatObject } from './utils/pathHelper';
import FormFieldsRenderer from './components/FormFieldsRenderer';
import './styles.css';

/**
 * 表单渲染器组件的 Props
 */
export interface FormRendererProps {
  /** 表单 Schema（包含 fields 和 formConfig） */
  schema?: FormSchema;
  /** 字段列表（与 schema 二选一） */
  fields?: FieldConfig[];
  /** 表单配置（与 schema 二选一） */
  formConfig?: FormConfig;
  /** 🆕 扩展组件（如工作流字段） */
  extraComponents?: ComponentMeta[];
  /** 表单初始值（仅用于初始化，不要作为受控属性使用） */
  value?: Record<string, any>;
  /** 值变化回调（父组件可监听，但不应将值传回 value） */
  onChange?: (values: Record<string, any>) => void;
  /** 提交回调 */
  onSubmit?: (values: Record<string, any>) => void | Promise<any>;
  /** 取消回调 */
  onCancel?: () => void;
  /** 只读模式 */
  readonly?: boolean;
  /** 是否显示提交按钮 */
  showSubmit?: boolean;
  /** 是否显示取消按钮 */
  showCancel?: boolean;
  /** 提交按钮文本 */
  submitText?: string;
  /** 取消按钮文本 */
  cancelText?: string;
  // 🎣 生命周期钩子（后续实现）
  beforeSubmit?: (values: Record<string, any>) => Record<string, any> | false | Promise<Record<string, any> | false>;
  afterSubmit?: (response?: any) => void | Promise<void>;
  onError?: (error: any) => void | Promise<void>;
}

/**
 * 表单渲染器组件暴露的方法
 */
export interface FormRendererRef {
  /** 提交表单（触发验证） */
  submit: () => Promise<void>;
  /** 重置表单 */
  reset: () => void;
}

const FormRenderer = forwardRef<FormRendererRef, FormRendererProps>((props, ref) => {
  const {
    schema,
    fields: propFields,
    formConfig: propFormConfig,
    extraComponents = [],
    onSubmit,
    showSubmit = false,
    showCancel = false,
    submitText = '提交',
    cancelText = '取消',
    onCancel,
  } = props;

  // 🔌 合并核心组件和扩展组件
  const allComponents = React.useMemo(() => {
    return [...COMPONENT_LIST, ...extraComponents];
  }, [extraComponents]);

  // 从 schema 或直接从 props 获取 fields 和 formConfig
  const fields = schema?.fields || propFields || [];
  const formConfig = schema?.formConfig || propFormConfig || {
    labelAlign: 'right',
    size: 'middle',
  };

  const [form] = Form.useForm();
  
  // 使用核心 hook 管理表单状态
  const { setFormData, fieldStates, handleValuesChange: coreHandleValuesChange } = useFormCore({ fields, form });

  // 🎯 初始化表单值（当 value prop 传入时）
  // 使用 ref 标记是否已初始化，防止用户编辑后被重新覆盖
  const isInitialized = React.useRef(false);
  
  React.useEffect(() => {
    // ✅ 只在第一次且有初始值时设置，避免覆盖用户已填写的数据
    if (!isInitialized.current && props.value && Object.keys(props.value).length > 0) {
      // 收集所有字段名称（包括嵌套字段）
      const collectFieldNames = (fieldList: FieldConfig[]): string[] => {
        const names: string[] = [];
        fieldList.forEach(field => {
          if (field.name) {
            names.push(field.name);
          }
          // 递归处理栅格布局内的字段
          if (field.type === 'grid' && field.children) {
            field.children.forEach(columnFields => {
              names.push(...collectFieldNames(columnFields));
            });
          }
        });
        return names;
      };

      const fieldNames = collectFieldNames(fields);
      // 将嵌套对象转换为扁平格式（Ant Design Form 需要）
      const flatValues = transformToFlatObject(props.value, fieldNames);
      form.setFieldsValue(flatValues);
      isInitialized.current = true; // 标记已初始化
      
      if (import.meta.env.DEV) {
        console.log('📥 表单初始值已设置:', flatValues);
      }
    }
  }, [props.value, form, fields]);

  // 🎯 自定义值变化处理：实时转换为嵌套对象
  const handleValuesChange = (changedValues: any, allValues: any) => {
    // 先调用核心的处理逻辑（联动规则等）
    coreHandleValuesChange(changedValues, allValues);
    
    // 实时转换为嵌套对象（用于父组件监听）
    if (props.onChange) {
      const nestedValues = transformToNestedObject(allValues);
      props.onChange(nestedValues);
    }
  };

  const handleSubmit = async () => {
    try {
      // 1. 表单验证
      const flatValues = await form.validateFields();
      
      // 🎯 2. 路径转换：将扁平数据转换为嵌套对象
      // 字段名支持点号和数组索引，如 'jenkins.serverId' 或 'users[0].name'
      const nestedValues = transformToNestedObject(flatValues);
      
      setFormData(nestedValues);
      
      // 3. beforeSubmit 钩子 - 允许修改提交数据或中断提交
      let finalValues = nestedValues;
      if (props.beforeSubmit) {
        try {
          const result = await props.beforeSubmit(nestedValues);
          if (result === false) {
            message.warning('提交已取消');
            return;
          }
          if (result && typeof result === 'object') {
            finalValues = result;
          }
        } catch (error) {
          console.error('❌ beforeSubmit 钩子失败:', error);
          message.error('提交前处理失败');
          if (props.onError) {
            await props.onError(error);
          }
          return;
        }
      }
      
      // 3. 执行提交
      let submitResult: any;
      if (onSubmit) {
        try {
          submitResult = await onSubmit(finalValues);
        } catch (error) {
          console.error('❌ 表单提交失败:', error);
          // 提交失败时触发 onError 钩子
          if (props.onError) {
            await props.onError(error);
          } else {
            message.error('提交失败，请稍后重试');
          }
          throw error; // 重新抛出，不执行 afterSubmit
        }
      } else {
        message.success('表单提交成功！');
      }
      
      // 4. afterSubmit 钩子 - 提交成功后的处理
      if (props.afterSubmit) {
        try {
          await props.afterSubmit(submitResult);
        } catch (error) {
          console.error('⚠️ afterSubmit 钩子失败:', error);
          // afterSubmit 失败不影响整体提交流程，只记录日志
        }
      }
    } catch (error) {
      // 验证失败 - 不显示弹窗，让表单元素自己显示错误即可
      console.error('❌ 表单验证/提交失败:', error);
      // ✅ 移除 message.error()，错误信息已在表单元素上显示
      
      // 触发 onError 钩子（验证失败也算错误）
      if (props.onError) {
        await props.onError(error);
      }
    }
  };

  const handleReset = () => {
    form.resetFields();
    setFormData({});
  };

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    submit: handleSubmit,
    reset: handleReset,
  }));

  if (fields.length === 0) {
    return (
      <div className="form-empty-state">
        表单为空
      </div>
    );
  }

  const layoutConfig = computeFormLayout(formConfig);

  return (
    <ComponentsContext.Provider value={allComponents}>
      <div className="form-container-padding form-renderer-compact">
        <Form
          form={form}
          layout={layoutConfig.layout}
          size={formConfig.size}
          colon={true}
          labelAlign={layoutConfig.labelAlign}
          labelCol={layoutConfig.labelCol}
          wrapperCol={layoutConfig.wrapperCol}
          onValuesChange={handleValuesChange}
        >
        {formConfig.title && (
          <h3 style={{ marginBottom: 24 }}>{formConfig.title}</h3>
        )}

        <FormFieldsRenderer
          fields={fields}
          formConfig={formConfig}
          fieldStates={fieldStates}
        />

          {(showSubmit || showCancel) && (
            <Form.Item 
              style={{ marginTop: 32, marginBottom: 0 }}
              wrapperCol={{ 
                offset: layoutConfig.labelCol?.span || 0, 
                span: layoutConfig.wrapperCol?.span || 24 
              }}
            >
              <div style={{ display: 'flex', gap: 8 }}>
                {showSubmit && (
                  <Button
                    type="primary"
                    htmlType="button"
                    onClick={handleSubmit}
                  >
                    {submitText}
                  </Button>
                )}
                {showCancel && (
                  <Button
                    htmlType="button"
                    onClick={onCancel || handleReset}
                  >
                    {cancelText}
                  </Button>
                )}
              </div>
            </Form.Item>
          )}
        </Form>
      </div>
    </ComponentsContext.Provider>
  );
});

FormRenderer.displayName = 'FormRenderer';

export default FormRenderer;
