import { isString } from '@pisell/utils';
import {
  nocobaseCpt2PisellCptMap,
  pisellCptMap,
  systemFields,
  formItemMetaMap,
} from './constants';
import { parseXRecordSchemaToChildSchemas } from '../data-source-sub-form/meta';

type UiSchema = {
  title: string;
  default?: string;
  enum: { label: string; value: string }[];
  'x-component': string;
  'x-component-props': Record<string, any>;
  'x-read-pretty': boolean;
  'x-validator'?: string;
  'x-display'?: 'visible' | 'hidden' | 'none';
  'x-pattern'?: 'editable' | 'disabled' | 'readPretty';
  'x-data-source'?: {
    sourceType?: string;
    type?: string;
    options?: Array<{ 
      id?: string;
      label: string | any; // 支持字符串或多语言对象
      value: string;
      color?: string;
    }>;
    labelField?: string;
    valueField?: string;
    dataSource?: any;
    extraParams?: Record<string, any>;
  };
  'x-record-schema'?: Record<string, any> | Record<string, any>[] | string;
  type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
};

/**
 * 将 MultiLanguageText 对象转为平台可解析的 i18n 格式
 * MultiLanguageText: { en, 'zh-CN', 'zh-HK', ja, pt, original }
 * i18n 格式:         { type: 'i18n', en, 'zh-CN', 'zh-HK', ... }
 *
 * 规则:
 * - 所有语言字段(含 original)均为空 → 返回 ''，避免低代码 i18n 图标被误亮
 * - 仅有 original 有值，其它翻译为空 → 返回纯字符串 original，正常显示但不绑定 i18n
 * - 有任意真实翻译 → 返回 i18n 对象，缺失的语言用 original 兜底
 */
const I18N_LANG_KEYS = ['en', 'zh-CN', 'zh-HK', 'ja', 'pt'];

const toI18nProp = (value: any): any => {
  if (!value) return value;
  if (typeof value === 'string') return value;
  if (typeof value === 'object' && value.type === 'i18n') return value;
  if (typeof value === 'object') {
    const original = value.original || '';
    const hasRealTranslation = I18N_LANG_KEYS.some((key) => !!value[key]);

    if (!hasRealTranslation) {
      return original;
    }

    const i18nResult: Record<string, any> = { type: 'i18n' };
    I18N_LANG_KEYS.forEach((key) => {
      i18nResult[key] = value[key] || original || '';
    });
    return i18nResult;
  }
  return value;
};

// 创建表单组
export const createFormGroup = (children: any[], groupTitle?: any, groupDescription?: any) => {
  return {
    children,
    componentName: 'FormGroup',
    title: '分组',
    props: {
      title: toI18nProp(groupTitle) || 'Group',
      description: toI18nProp(groupDescription) || '',
      showTitle: true,
      showDescription: true,
      showBackgroundColor: true,
      backgroundColor: '#F9FAFB',
    },
  };
};

// 创建提交按钮
export const createSubmitButton = (props: any = {}) => {
  return {
    componentName: 'SubmitButton',
    title: '提交',
    props: {
      type: 'primary',
      size: 'large',
      status: 'normal',
      childrenString: {
        type: 'i18n',
        en: 'Submit',
        'zh-CN': '提交',
        'zh-HK': '提交',
      },
      confirmConfig: {
        enable: false,
      },
      toastConfig: {
        enable: true,
        showAfterSubmit: true,
        title: {
          type: 'i18n',
          en: 'Submitted successfully',
          'zh-CN': '提交成功',
          'zh-HK': '提交成功',
        },
      },
      refreshData: true,
      afterSubmitType: 'none',
      ...props,
    },
    children: [],
  };
};

// 创建表单项子项
export const createFormItemChildren = (item: {
  name: string;
  uiSchema: UiSchema;
}) => {
  let props: Record<string, any> = item.uiSchema['x-component-props'] || {};
  let componentName = item.uiSchema['x-component'];
  if (
    ['Select', 'Radio.Group', 'Checkbox.Group'].includes(
      item.uiSchema['x-component']
    ) &&
    item.uiSchema?.enum?.length > 0
  ) {
    if (
      ['Radio.Group', 'Checkbox.Group'].includes(item.uiSchema['x-component'])
    ) {
      props.direction = 'horizontal';
    }
    props.options = item?.uiSchema?.enum || [];
  }

  if (item.uiSchema['x-read-pretty']) {
    props.disabled = item.uiSchema['x-read-pretty'];
  }

  if (item.uiSchema['x-component'] === 'ColorPicker') {
    props.defaultValue = item.uiSchema.default;
  }

  return {
    componentName,
    props,
  };
};

const modeMap: Record<string, any> = {
  add: 'edit',
  edit: 'edit',
  view: 'view',
};


export const createFormItemSchema = (
  item: {
    name: string;
    uiSchema: UiSchema;
    schema?: Record<string, any>;
    children?: any[];
    _children?: any[];
    interface?: string;
  },
  mode: string
) => {
  const { name, uiSchema } = item;
  const {
    title,
    'x-component': xComponent,
    'x-validator': validator,
    'x-read-pretty': readPretty,
    default: defaultValue,
    'x-component-props': xProps,
    'x-pattern': xPattern,
    'x-display': xDisplay,
    'x-description': xDescription,
    type,
  } = uiSchema as any;
  let cptTitle = undefined;

  // 根据 x-pattern 和 x-display 确定 renderMode
  // 优先级: x-display > x-pattern > x-read-pretty > x-component-props.renderMode > mode 参数
  let renderMode = modeMap[mode] || 'edit';
  
  // 先检查 x-component-props 中是否已有 renderMode
  if (xProps?.renderMode) {
    renderMode = xProps.renderMode;
  }
  
  // x-read-pretty 兼容旧逻辑（优先级高于 x-component-props）
  if (readPretty) {
    renderMode = 'view';
  }
  
  // x-pattern 映射到 renderMode（优先级更高）
  if (xPattern === 'readPretty') {
    renderMode = 'view';
  } else if (xPattern === 'disabled') {
    renderMode = 'disabled';
  } else if (xPattern === 'editable') {
    renderMode = 'edit';
  }
  
  // x-display = 'hidden' 优先级最高
  if (xDisplay === 'hidden') {
    renderMode = 'hidden';
  }

  // 构建 props: 先设置默认值，再用 x-component-props 覆盖，最后设置 renderMode
  let props: Record<string, any> = {
    // 默认值
    label: toI18nProp(title),
    name,
    allowClear: true,
    placeholder: {
      type: 'i18n',
      'en': 'Enter',
      'zh-CN': '请输入',
      'zh-HK': '請輸入',
    },
    // x-component-props 中的所有字段直接映射，可以覆盖上面的默认值
    ...xProps,
    // renderMode 最终计算结果（综合了所有来源）
    renderMode,
    // 辅助说明文字（来自 registry item 的 description），转为 i18n 格式
    ...(xDescription ? { extra: toI18nProp(xDescription) } : {}),
  };
  
  // 如果 x-component-props 中存在 required 字段，额外添加 requiredobj
  if (xProps?.required !== undefined) {
    props.requiredobj = {
      required: xProps.required,
    };
  }
  
  let componentName = xComponent;

  let childrenSchema: any[] = [];
  let propertiesSchema: Record<string, any> = {};

  if (item?.interface === 'phone') {
    cptTitle = '电话号码输入';
    componentName = 'Input.Phone';
  }
  if (item?.interface === 'mobile') {
    cptTitle = '手机号码输入';
    componentName = 'Input.Mobile';
  }

  if (xComponent === 'Percent') {
    cptTitle = '百分比输入';
  }

  if (item?.interface === 'url') {
    cptTitle = '链接输入';
    componentName = 'Input.URL';
  }

  if (item?.interface === 'attachmentUrl') {
    cptTitle = '多媒体文件上传';
    componentName = 'Upload';
  }

  if (item?.interface === 'i18nAttachment') {
    cptTitle = '多媒体文件上传';
    componentName = 'Upload';
    props.enableMultilingual = true;
  }

  if (validator && validator !== 'integer') {
    if (validator === 'email') {
      cptTitle = '电子邮箱输入';
      componentName = 'Input.Email';
    }
    props.typeobj = {
      type: validator,
      enabled: true,
    };
  }

  // 如果类型是 integer，设置 precision 为 0，只允许输入整数
  if (type === 'integer' && (xComponent === 'InputNumber' || xComponent === 'Percent')) {
    props.precision = 0;
  }

  if (xComponent === 'Input.JSON' && item?.interface !== 'i18nInput') {
    const jsonChildren = item._children || item.children || [];

    // 如果有children属性,递归创建子表单项
    if (jsonChildren && jsonChildren.length > 0) {
      props.prefix = name;
      childrenSchema = jsonChildren.map((child: any) =>
        createFormItemSchema(child, mode)
      );
      // 同时构建 properties 格式
      jsonChildren.forEach((child: any) => {
        const childSchema = createFormItemSchema(child, mode);
        propertiesSchema[child.name] = childSchema;
      });
    } else {
      componentName = 'Input.InputJSON';
      props.autoSize = {
        minRows: 4,
      };
      
      // 根据type类型生成不同的normalize和校验逻辑
      const fieldType = type || 'object';
      let normalizeValue = '';
      let validatorValue = '';
      
      normalizeValue = '(value) => {\n  try {\n    if (typeof value === \'string\' && value.trim() !== \'\') {\n      const trimmedValue = value.trim();\n      // 只有以{或[开头才尝试转换\n      if (trimmedValue.startsWith(\'{\') || trimmedValue.startsWith(\'[\')) {\n        return JSON.parse(trimmedValue);\n      }\n    }\n  } catch(error) {\n    console.log(error)\n  }\n  return value\n}';
      validatorValue = "async (value) => {\n  try {\n    if (typeof value === 'string' && value.trim() !== '') {\n      const trimmedValue = value.trim();\n      // 确保JSON以{或[开头，以避免纯数字或字符串通过校验\n      if (!trimmedValue.startsWith('{') && !trimmedValue.startsWith('[')) {\n        return Promise.reject(new Error('JSON必须是对象或数组，请以{或[开头'));\n      }\n      JSON.parse(trimmedValue);\n    }\n  } catch (err) {\n    return Promise.reject(new Error(err.message));\n  }\n}";
      
      props.normalize = {
        type: 'JSExpression',
        value: normalizeValue,
      };
      props.getValueProps = {
        type: 'JSExpression',
        value:
          '(value) => {\n  try {\n    // 使用严格检查：null/undefined不转换，其他对象类型都转换\n    if (value !== null && value !== undefined && typeof value === \'object\') {\n      return { value: JSON.stringify(value, null, 2) };\n    }\n    return { value: value };\n  } catch(error) {\n    console.log(error)\n  }\n  return {value: value}\n}',
      };
      props.validator = {
        type: 'JSExpression',
        value: validatorValue,
      };
    }
  }

  if (item?.interface === 'i18nInput') {
    cptTitle = '多语言输入';
    componentName = 'Translation';
  }

  // 注入默认值
  props.defaultValue = defaultValue;

  // 获取选项配置
  const dataSourceConfig = (uiSchema as any)?.['x-data-source'] || item?.schema?.['x-data-source'];
  const recordSchemaConfig = (uiSchema as any)?.['x-record-schema'] || item?.schema?.['x-record-schema'];
  const isRecordListWrapper =
    item?.interface === 'RecordListWrapper' || xComponent === 'RecordListWrapper';

  if (isRecordListWrapper) {
    cptTitle = '记录列表包装器';
    componentName = 'RecordListWrapper';
    props.xRecordSchema = recordSchemaConfig;

    // 自动将 recordSchemaConfig 解析为子节点 Schema，与 JsonSetter 的 setValue 保持一致，
    // 避免用户必须在低代码面板手动触发 JsonSetter 才能渲染子表单字段。
    if (recordSchemaConfig) {
      childrenSchema = parseXRecordSchemaToChildSchemas(recordSchemaConfig);
    } else {
      childrenSchema = [];
    }
  }
  
  if (
    (['Select', 'Radio.Group', 'Checkbox.Group'].includes(xComponent) ||
      isRecordListWrapper) &&
    (uiSchema?.enum?.length > 0 || dataSourceConfig || isRecordListWrapper)
  ) {
    if (['Radio.Group', 'Checkbox.Group'].includes(xComponent)) {
      props.direction = 'horizontal';
      props.placeholder = "";
    } else {
      if (type === 'array') {
        props.mode = 'multiple';
      }
      props.styleType = 'antd';
      props.showSearch = true;
      props.optionFilterProp = 'label';
      props.placeholder = {
        type: 'i18n',
        'en': 'Select an option',
        'zh-CN': '请选择一个选项',
        'zh-HK': '請選擇一個選項',
      };

      if (props.mode === "multiple") {
        props.selectAll = true;
        props.isShowDropdown = true;
        props.placeholder = {
          type: 'i18n',
          'en': 'Select one or more options',
          'zh-CN': '请选择一个或多个选项',
          'zh-HK': '請選擇一個或多個選項',
        };
      }
    }
    
    // 统一的选项配置处理
    const optionConfig = dataSourceConfig || {};
    
    // 设置 optionSourceType
    props.optionSourceType = optionConfig?.type || '';
    
    // 根据 sourceType 设置不同的配置
    if (props.optionSourceType === 'default') {
      // 优先使用 optionConfig.options，其次兼容旧的 enum 格式
      const rawOptions = optionConfig.options || uiSchema?.enum || [];
      
      // 转换多语言格式的 label 为组件可识别的 i18n 格式
      props.options = rawOptions.map((option: any) => {
        const label = option.label;
        
        // 如果 label 是多语言对象格式，转换为 i18n 格式
        if (label && typeof label === 'object' && !label.type) {
          return {
            ...option,
            label: {
              type: 'i18n',
              'en': label.en || label.original || '',
              'zh-CN': label['zh-CN'] || label.original || '',
              'zh-HK': label['zh-HK'] || label.original || '',
            }
          };
        }
        
        // 如果已经是 i18n 格式或者是字符串，直接返回
        return option;
      });
    } else if (props.optionSourceType === 'api') {
      // API 类型需要设置 labelField 和 valueField
      if (optionConfig?.labelField) {
        props.labelField = optionConfig.labelField;
      }
      if (optionConfig?.valueField) {
        props.valueField = optionConfig.valueField;
      }
      if (optionConfig?.dataSource) {
        props.dataSource = optionConfig.dataSource;
      }
      if (optionConfig?.extraParams) {
        props.extraParams = optionConfig.extraParams;
      }
    }
  }

  if (xComponent === 'TimePicker') {
    props.format = 'HH:mm';
    props.placeholder = {
      type: 'i18n',
      'en': 'Select a time',
      'zh-CN': '请选择时间',
      'zh-HK': '請選擇時間',
    };
    props.defaultValue = props.defaultValue || null;
  }

  if (xComponent === 'DatePicker') {
    props.format = props.dateFormat || 'YYYY-MM-DD';
    props.showTime = false;
    props.placeholder = {
      type: 'i18n',
      'en': 'Select a date',
      'zh-CN': '请选择日期',
      'zh-HK': '請選擇日期',
    };
    props.defaultValue = null;
  }

  if (xComponent === 'ColorPicker') {
    props.defaultValue = defaultValue;
  }

  if (xComponent === 'Switch') {
    props.placeholder = '';
    props.allowClear = false;
  }

  const _componentName = nocobaseCpt2PisellCptMap[componentName];

  // 确定 schema type
  let schemaType: 'void' | 'string' | 'number' | 'object' | 'array' | 'boolean' = 'string';
  if (type) {
    schemaType = type as any;
  } else if (xComponent === 'InputNumber' || xComponent === 'Percent') {
    schemaType = 'number';
  } else if (componentName === 'RecordListWrapper') {
    schemaType = 'array';
  } else if (xComponent === 'Input.JSON' || item?.interface === 'i18nInput') {
    schemaType = 'object';
  } else if (['Checkbox.Group', 'Select'].includes(xComponent) && props.mode === 'multiple') {
    schemaType = 'array';
  } else if (xComponent === 'Switch' || xComponent === 'Checkbox') {
    schemaType = 'boolean';
  }

  // 构建完整的 UI Schema 格式
  const schema: any = {
    // 基础属性
    type: schemaType,
    name: name,
    title: title,

    // 组件相关
    'x-component': _componentName,
    'x-component-props': props,

    // 包装器 (FormItem 作为 decorator)
    'x-decorator': 'FormItem',
    'x-decorator-props': {
      label: title,
    },

    // 默认值
    default: defaultValue,

    // 校验
    ...(validator && { 'x-validator': validator }),

    // children 节点 (兼容旧格式和新格式)
    ...(childrenSchema.length > 0 && { children: childrenSchema }),
    ...(Object.keys(propertiesSchema).length > 0 && { properties: propertiesSchema }),

    // 设计器相关 (如果需要)
    // 'x-initializer': undefined,
    // 'x-settings': undefined,
    // 'x-toolbar': undefined,

    // 兼容旧格式: 保留 componentName 供旧代码使用
    componentName: _componentName,
    props,
  };

  return schema;
};

type FieldOption = {
  isGroup: boolean;
  label: string;
  value: string;
  isShow: boolean;
  children: FieldOption[];
};

// 表单schema转换为字段选项
export const formSchema2PisellFieldsOptions = (
  formSchema: any,
  allFields: any[]
) => {
  if (
    !['DataSourceForm', 'FormGroup', 'DataSourceWrapper'].includes(
      formSchema.componentName
    )
  ) {
    return [];
  }

  const allFieldMap = allFields.reduce((acc, item) => {
    acc[item.name] = item;
    return acc;
  }, {});

  let fieldsOptions: FieldOption[] = [];
  const showFields: any[] = [];

  const hiddenFields: FieldOption[] = [];

  if (!formSchema?.children) {
    return [];
  }

  formSchema.children.forEach((item: any) => {
    // 是基础formItem组件
    if (pisellCptMap[item.componentName]) {
      showFields.push(item.props.name);
      fieldsOptions.push({
        isGroup: false,
        label:
          item.props.label ||
          allFieldMap[item.props.name]?.uiSchema?.title ||
          item.props.name,
        value: item.id,
        isShow: true,
        children: [],
      });
    } else if (item.componentName === 'FormGroup') {
      fieldsOptions.push({
        isGroup: true,
        label: item.props.title,
        value: item.id,
        isShow: true,
        children: item?.children?.map((children: any) => {
          showFields.push(children.props.name);
          return {
            isGroup: false,
            label:
              children.props.label ||
              allFieldMap[children.props.name]?.uiSchema?.title ||
              children.props.name,
            value: children.id,
            isShow: true,
            children: [],
          };
        }),
      });
    }
  });

  allFields.forEach((item) => {
    if (!showFields.includes(item.name)) {
      hiddenFields.push({
        isGroup: false,
        label:
          item.uiSchema?.title ||
          allFieldMap[item.name]?.uiSchema?.title ||
          item.name,
        value: item.name,
        isShow: false,
        children: [],
      });
    }
  });

  fieldsOptions = [
    ...fieldsOptions,
    {
      isGroup: true,
      label: 'Hidden',
      value: 'hidden',
      isShow: true,
      children: hiddenFields,
    },
  ];

  return fieldsOptions;
};

// 字段转换为schema
export const fields2ChildrenSchemas = (fields: any[], mode: string) => {
  return fields
    .filter(
      (field: any) =>
        field.uiSchema &&
        !field.uiSchema['x-read-pretty'] &&
        !systemFields.includes(field.name)
    )
    .map((field: any) => {
      return createFormItemSchema(field, mode);
    })
    .filter((item: any) => !!item.componentName);
};

// 设置变量
export const setVariables = (
  target: any,
  {
    label,
    value,
  }: {
    label: string;
    value: any;
  }
) => {
  const variables = target.getProps().getPropValue('_variables');
  target.getProps().setPropValue('_variables', {
    ...variables,
    [label]: value,
  });
};

// 批量设置变量
export const setBatchVariables = (
  target: any,
  variables: Array<{
    /**
     * currentFields 当前表单字段列表
     * dataSourceTitle 数据源标题
     * dataSourceValue 数据源值
     * cptValuesVariables 组件值变量
     */
    label:
      | 'currentFields'
      | 'dataSourceTitle'
      | 'dataSourceValue'
      | 'cptValuesVariables'
      | 'currentValueVariables'
      | 'dataSourceVariables';
    value: any;
  }>
) => {
  const existingVariables = target.getProps().getPropValue('_variables') || {};
  const newVariables = variables.reduce(
    (acc, { label, value }) => ({
      ...acc,
      [label]: value,
    }),
    existingVariables
  );

  target.getProps().setPropValue('_variables', newVariables);
};

// 获取当前节点所有变量
export const getAllVariables = (target: any) => {
  return target.getProps().getPropValue('_variables');
};

// 获取当前节点单个变量
export const getVariable = (target: any, label: string) => {
  return target.getProps().getPropValue('_variables')?.[label];
};

// 清除当前节点所有变量
export const clearVariables = (target: any) => {
  return target.getProps().setPropValue('_variables', null);
};

type VariablesItemType = {
  componentName: string;
  title: string;
  id: string;
  variables: Record<string, any>;
};

// 获取当前节点父节点所有变量
const getParentVariables = (target: any) => {
  let parent = target.node;
  const variables: VariablesItemType[] = [];

  while (parent) {
    const { componentName, title, id } = parent;
    const _variables = parent.getProps().getPropValue('_variables');

    const strTitle = isString(title) ? title : title['zh-CN'];

    if (_variables) {
      variables.push({
        componentName,
        title: strTitle,
        id,

        variables: _variables,
      });
    }

    parent = parent.parent;
  }

  return variables;
};

// 获取数据源变量
export const getDataSourceVariables = (target: any) => {
  const variables = getParentVariables(target);

  return variables
    ?.map((item: VariablesItemType) => {
      return {
        label: item.title,
        value: item.id,
        children: item.variables.dataSourceVariables,
        isVariable: true,
      };
    })
    .filter((item) => item?.children?.length);
};

export const getCurrentValueVariables = (target: any) => {
  const ds = target?.getProps()?.getPropValue('_variables')?.dataSourceValue;
  if (ds?.fromSettingMeta || ds?.fromDeviceSettingMeta) {
    return [];
  }
  
  const variables = getParentVariables(target);
 
  const currentDataSourceTitle = getVariable(target, 'dataSourceTitle');

  const currentValueVariables: any[] = [
    {
      label: currentDataSourceTitle,
      value: 'server',
    },
  ];

  variables.forEach((item: VariablesItemType) => {
    if (item.variables?.currentValueVariables?.length) {
      currentValueVariables.push({
        label: item.title,
        value: item.id,
        children: item.variables.currentValueVariables,
        isVariable: true,
      });
    }
  });

  return currentValueVariables;
};

export const getCptValuesVariables = (target: any) => {
  const variables = getParentVariables(target);
  return variables
    ?.map((item: VariablesItemType) => {
      return {
        label: `${item.title}-${item?.variables?.dataSourceTitle || ''}`,
        value: item.id,
        children: item.variables.cptValuesVariables,
        isVariable: true,
      };
    })
    .filter((item) => item?.children?.length);
};

export const getDataSourceValue = (target: any) => {
  const variables = getParentVariables(target);
  return variables?.find((item) => item.variables.dataSourceValue)?.variables
    .dataSourceValue;
};
