import { isString } from '@pisell/utils';
import {
  nocobaseCpt2PisellCptMap,
  pisellCptMap,
  systemFields,
  formItemMetaMap,
} from './constants';

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;
  type: 'string' | 'number' | 'boolean' | 'array' | 'object';
};

// 创建表单组
export const createFormGroup = (children: any[]) => {
  return {
    children,
    componentName: 'FormGroup',
    title: '分组',
    props: {
      title: 'Group',
      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;
    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,
  } = uiSchema;

  let cptTitle = undefined;

  let props: Record<string, any> = {
    ...xProps,
    label: title,
    name,
    renderMode: modeMap[mode] || 'edit',
    allowClear: true,
  };
  let componentName = xComponent;

  let childrenSchema: any[] = [];

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

  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,
    };
  }

  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)
      );
    } else {
      componentName = 'Input.InputJSON';
      props.autoSize = {
        minRows: 4,
      };
      // props.validateTrigger = "onBlur";
      props.normalize = {
        type: 'JSExpression',
        value:
          '(value) => {\n  try {\n    return JSON.parse(value);\n  } catch(error) {\n    console.log(error)\n  }\n  return value\n}',
      };
      props.getValueProps = {
        type: 'JSExpression',
        value:
          '(value) => {\n  try {\n   return { value: value != "" && typeof value === \'object\' ? JSON.stringify(value, null, 2) : value};\n  } catch(error) {\n    console.log(error)\n  }\n  return {value: value}\n}',
      };
      props.validator = {
        type: 'JSExpression',
        value:
          "async (value) => {\n try {\n    if (typeof value === 'string' && value.trim() !== '') {\n      JSON.parse(value);\n    }\n  } catch (err) {\n    return Promise.reject(new Error(err.message));\n  }\n}",
      };
    }
  }

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

  if (
    ['Select', 'Radio.Group', 'Checkbox.Group'].includes(xComponent) &&
    uiSchema?.enum?.length > 0
  ) {
    if (['Radio.Group', 'Checkbox.Group'].includes(xComponent)) {
      props.direction = 'horizontal';
    } else {
      props.styleType = 'antd';
      props.showSearch = true;
      props.isShowDropdown = true;
      props.optionFilterProp = 'label';
      if (props.mode === "multiple") {
        props.selectAll = true;
      }
    }
    props.optionSourceType = 'default';
    props.options = uiSchema?.enum || [];
  }

  if (xComponent === 'TimePicker') {
    props.format = 'HH:mm';
    props.placeholder = '';
    props.defaultValue = props.defaultValue || null;
  }

  if (xComponent === 'DatePicker') {
    props.format = props.dateFormat || 'YYYY-MM-DD';
    props.showTime = false;
    props.placeholder = '';
    props.defaultValue = null;
  }

  // 如果设置了x-read-pretty，则设置为只读
  if (readPretty) {
    props.renderMode = 'view';
  }

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

  const _componentName = nocobaseCpt2PisellCptMap[componentName];

  return {
    title: cptTitle || formItemMetaMap[_componentName]?.title,
    componentName: _componentName,
    props,
    children: childrenSchema,
  };
};

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 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;
};
