import { buildOption } from '/@/utils/helper/designHelper';
import { FormProps } from '/@/components/Form';
import { separator } from '/@/views/workflow/design/bpmn/config/info';
import { TaskApproveOpinion, WorkFlowFormParams } from '/@/model/workflow/bpmnConfig';
import { FormConfigItem } from '/@/model/workflow/formSetting';
import { FormSchema } from '/@/components/Form';
import { TableItem } from '/@/model/workflow/formSetting';
import { disableTypes, hiddenComponentType, requiredDisabled } from '/@bpmn/config/formPermission';
/*
**根据权限 修改JSON配置**
data{
  formJson 表单json配置
  formConfigChildren 工作流节点表单权限配置
  formConfigKey 唯一节点表单key
  opinions  意见簿意见
  opinionsComponents  意见簿组件
  }
  isViewProcess 是否查看流程
  uploadComponentIds: 所有上传文件的文件夹id    【因为流程需要统计每个节点的附件汇总】
*/
export function changeFormJson(
  data: {
    formJson: any; // 表单json配置 FormJson | FormProps
    formConfigChildren: Array<FormConfigItem>; // 工作流节点表单权限配置
    formConfigKey: String; //唯一节点表单key
    opinions?: Array<TaskApproveOpinion> | undefined; //意见簿意见
    opinionsComponents?: Array<string> | undefined; //意见簿组件
  },
  isViewProcess: Boolean,
  uploadComponentIds: Array<string>,
) {
  const returnData = handlerFormPermission(
    data.formJson.list ? buildOption(data.formJson, false) : data.formJson,
    data.formConfigChildren,
    data.formConfigKey,
    isViewProcess,
    { uploadComponentIds, opinions: data.opinions, opinionsComponents: data.opinionsComponents },
  );
  // uploadComponent 带上所有上传文件的文件夹id
  return returnData;
}
// 获取工作流表单权限map
/*
  返回Map
  [
    字段唯一Key:{
      {
        edit:是否可编辑权限,
        view:是否可查看权限,
        disabled:是否禁用权限,
        children:[] 子表数据
      }
    }
  ]
  */
export function getPermissionConfigMap(formConfigChildren) {
  const map = new Map();
  formConfigChildren.forEach((element) => {
    map.set(element.key, element);
  });

  return map;
}
function handlerFormPermission(
  buildOptionJson: FormProps,
  formConfigChildren,
  formKey,
  isViewProcess,
  otherParams,
) {
  const permissionConfigMap = getPermissionConfigMap(formConfigChildren);
  const formShow: Number = 0; //表单是否有显示的组件，有则大于0
  buildOptionJson.schemas = schemeList(
    buildOptionJson.schemas,
    permissionConfigMap,
    formKey,
    formShow,
    isViewProcess,
    otherParams,
  );
  return {
    buildOptionJson,
    uploadComponentIds: otherParams.uploadComponentIds,
  };
}

function schemeList(
  schemas,
  permissionConfigMap,
  formKey,
  formShow,
  isViewProcess,
  otherParams,
  tableName?,
) {
  schemas = schemas.map((schema) => {
    if (['Card', 'Grid', 'Tab'].includes(schema.component)) {
      formShow += 1;
      if (schema.children && schema.children.length > 0) {
        schema.children.forEach((ele2) => {
          if (ele2.list && ele2.list.length > 0) {
            ele2.list = schemeList(
              ele2.list,
              permissionConfigMap,
              formKey,
              formShow,
              isViewProcess,
              otherParams,
              tableName,
            );
          }
        });
      }
    } else if (schema.component === 'TableLayout') {
      formShow += 1;
      if (schema.children && schema.children.length > 0) {
        schema.children.forEach((ele2) => {
          if (ele2.list && ele2.list.length > 0) {
            ele2.list.forEach((ele3) => {
              if (ele3.children && ele3.children.length > 0) {
                ele3.children = schemeList(
                  ele3.children,
                  permissionConfigMap,
                  formKey,
                  formShow,
                  isViewProcess,
                  otherParams,
                  tableName,
                );
              }
            });
          }
        });
      }
    } else if (schema.component == 'SubForm') {
      if (
        schema.componentProps &&
        schema.componentProps.columns &&
        schema.componentProps.columns.length > 0
      ) {
        const permissionConfig = permissionConfigMap.has(schema.key)
          ? permissionConfigMap.get(schema.key)
          : null;

        // 查看流程
        if (isViewProcess) {
          schema.dynamicDisabled = true;
        }
        if (!permissionConfig?.view) {
          schema.show = false;
        } else {
          formShow += 1;
          if (!permissionConfig?.edit) {
            schema.dynamicDisabled = true;
          }
        }
        schema.componentProps.columns = schema.componentProps.columns.map((ele3) => {
          const tableItemPermissionConfig = permissionConfig.children.find((x) => {
            if (x.key) {
              return x.key === ele3.key;
            }
            if (x.fieldId) {
              return x.fieldId === ele3.dataIndex;
            }
          });

          return getSchemePermissionItem(
            ele3,
            tableItemPermissionConfig,
            formKey,
            isViewProcess,
            otherParams,
          );
        });
      }
    } else if (schema.component == 'OneForOne') {
      const permissionConfig = permissionConfigMap.has(schema.key)
        ? permissionConfigMap.get(schema.key)
        : null;
      if (!permissionConfig?.view) {
        schema.show = false;
      } else {
        formShow += 1;
      }
      if (schema.componentProps?.childSchemas?.length > 0) {
        const onePermissionConfigMap = getPermissionConfigMap(permissionConfig.children);
        schema.componentProps.childSchemas = schemeList(
          schema.componentProps.childSchemas,
          onePermissionConfigMap,
          formKey,
          formShow,
          isViewProcess,
          otherParams,
          schema.field,
        );
      }
    } else {
      const permissionConfig = permissionConfigMap.has(schema.key)
        ? permissionConfigMap.get(schema.key)
        : null;

      schema = getSchemePermissionItem(
        schema,
        permissionConfig,
        formKey,
        isViewProcess,
        otherParams,
        tableName,
      );
      if (permissionConfig?.view) {
        formShow += 1;
      }
    }

    return schema;
  });

  return formShow > 0 ? schemas : null;
}

function getSchemePermissionItem(
  schema,
  permissionConfig,
  formKey,
  isViewProcess,
  otherParams,
  tableName?,
) {
  if (permissionConfig) {
    //查看
    if (schema.componentProps) {
      schema.componentProps.isShow = permissionConfig.view;
    } else {
      schema.show = permissionConfig.view;
    }
    // 必填

    if (schema.componentProps) schema.componentProps.required = permissionConfig.required;
    schema.required = permissionConfig.required;
    //编辑

    if (schema.componentProps) schema.componentProps.disabled = !permissionConfig.edit;
    schema.dynamicDisabled = !permissionConfig.edit;

    // 查看流程
    if (isViewProcess) {
      schema.dynamicDisabled = true;
    } else if (schema.type == 'info') {
      schema.dynamicDisabled = false;
    }
  } else {
    schema.show = false;
    schema.dynamicDisabled = true;
  }
  // 修改意见簿
  if (schema.component == 'Opinion') {
    const key = formKey + separator + schema.key;
    schema.defaultValue = [];
    if (otherParams.opinionsComponents?.includes(key)) {
      schema.defaultValue = otherParams.opinions[key];
    }
  }
  // 上传组件集合
  if (schema.component == 'Upload') {
    let key = '';
    if (tableName) {
      key = formKey + separator + tableName + separator + schema.field;
    } else {
      key = formKey + separator + schema.field;
    }

    otherParams.uploadComponentIds.push(key);
  }
  if (schema.componentType == 'SunForm') {
    schema.componentProps.columns = schema.componentProps.columns.map((ele3) => {
      const tableItemPermissionConfig = permissionConfig.children.find((x) => {
        if (x.key) {
          return x.key === ele3.key;
        }
        if (x.fieldId) {
          return x.fieldId === ele3.dataIndex;
        }
      });

      return getSchemePermissionItem(
        ele3,
        tableItemPermissionConfig,
        formKey,
        isViewProcess,
        otherParams,
      );
    });
  }
  if (permissionConfig?.isSubTable) {
    // 子表单上传组件集合
    if (schema.componentType == 'Upload') {
      const key =
        formKey + separator + permissionConfig.tableName + separator + permissionConfig.fieldId;

      otherParams.uploadComponentIds.push(key);
    }
  }
  return schema;
}

// 根据工作流页面权限，设置表单属性（必填，禁用，显示）
export async function changeWorkFlowForm(formProps: FormProps, obj: WorkFlowFormParams) {
  const {
    formConfigChildren,
    formConfigKey,
    opinions,
    opinionsComponents,
    isViewProcess,
    uploadIds,
    formModels,
  } = obj;
  const returnData: {
    buildOptionJson: FormProps;
    uploadComponentIds: Array<string>;
    formModels: any;
    isViewProcess: boolean;
  } = {
    buildOptionJson: {}, //重新的配置Json文件
    uploadComponentIds: [], //
    formModels,
    isViewProcess: false,
  };
  try {
    const { buildOptionJson, uploadComponentIds } = await changeFormJson(
      {
        formJson: formProps,
        formConfigChildren,
        formConfigKey: formConfigKey,
        opinions,
        opinionsComponents,
      },
      isViewProcess,
      uploadIds,
    );
    returnData.buildOptionJson = buildOptionJson;
    returnData.uploadComponentIds = uploadComponentIds;
    return returnData;
  } catch (error) {
    return returnData;
  }
}
// 根据表单json 生成权限配置
export function getWorkflowPermissionConfig(schema) {
  let children: Array<TableItem> = [];
  if (schema.length > 0) {
    children = getSchemasConfig(schema);
  }
  return children;
}

function getSchemasConfig(list: FormSchema[]) {
  const arr: Array<TableItem> = [];
  if (list && list.length > 0) {
    list.forEach((ele1) => {
      if (['Card', 'Grid', 'Tab'].includes(ele1.component)) {
        if (ele1.children && ele1.children.length > 0) {
          ele1.children.forEach((ele2) => {
            if (ele2.list && ele2.list.length > 0) {
              arr.push(...getSchemasConfig(ele2.list));
            }
          });
        }
      } else if (ele1.component === 'TableLayout') {
        if (ele1.children && ele1.children.length > 0) {
          ele1.children.forEach((ele2) => {
            if (ele2.list && ele2.list.length > 0) {
              ele2.list.forEach((ele3) => {
                if (ele3.children && ele3.children.length > 0) {
                  arr.push(...getSchemasConfig(ele3.children));
                }
              });
            }
          });
        }
      } else if (ele1.component == 'SubForm') {
        arr.push(getTableConfig(ele1));
      } else if (ele1.component === 'OneForOne') {
        const obj: TableItem = getItemConfig(ele1);
        obj.isSubTable = true;
        obj.showChildren = false;
        const tempList: FormSchema[] = ele1.componentProps?.childSchemas || [];
        obj.children.push(...getSchemasConfig(tempList));
        arr.push(obj);
      } else {
        arr.push(getItemConfig(ele1));
      }
    });
  }
  return arr;
}

function getItemConfig(element) {
  const children: Array<TableItem> = [];
  let required = true;
  let view = true;
  let edit = true;
  let disabled = false;
  let isSaveTable = false; //组件是否存表
  let options = {}; //组件其它参数
  const type = element.type;
  if (element.componentProps) {
    // 必填权限 根据表单中是否必填
    required = element.componentProps.required;
    // 查看权限 默认打开
    view = true;
    //编辑权限 如果表单中是否禁用开启了 那就是不可编辑
    edit = element.componentProps.disabled ? false : true;
  }
  if (disableTypes.includes(element.type)) {
    required = false;
    view = true;
    edit = false;
    disabled = true;
  }
  if (requiredDisabled.includes(element.type)) {
    required = false;
  }
  // 隐藏组件权限不要设置
  if (element.type === hiddenComponentType) {
    required = false;
    view = false;
    edit = false;
    disabled = true;
  }
  if (element.type === 'input' && element.componentProps.isSave) {
    required = false;
    view = true;
    edit = false;
    disabled = true;
    isSaveTable = true;
  }
  if (element.type === 'info') {
    options = {
      infoType: element.componentProps.infoType,
    };
  }
  let fieldId = element.field;
  if (element.type === 'iframe') {
    fieldId = '';
    options = {
      ...element.componentProps,
    };
  }
  return {
    required,
    view,
    edit,
    disabled,
    isSaveTable,
    tableName: '',
    fieldName: element.label,
    fieldId: fieldId,
    isSubTable: false,
    showChildren: true,
    type,
    key: element.key,
    children,
    options,
    defaultValue:
      element.type == 'hiddenComponent'
        ? element.defaultValue
        : element.componentProps?.defaultSelect
        ? element.componentProps.defaultSelect
        : element.componentProps.defaultValue,
  };
}
function getTableConfig(element, tableName?: string) {
  const children: Array<TableItem> = [];
  const fieldId = element.componentType == 'SunForm' ? element.mainKey : element.field;
  if (
    element.componentProps &&
    element.componentProps.columns &&
    element.componentProps.columns.length > 0
  ) {
    element.componentProps.columns.forEach((ele2) => {
      if (ele2.dataIndex !== undefined || ele2.componentType == 'SunForm')
        children.push(getTableItemConfig(fieldId, ele2));
    });
  }
  return {
    required: true,
    view: true,
    edit: true,
    disabled: false,
    isSubTable: true,
    showChildren: false,
    tableName: tableName || element.field,
    fieldName: element.componentType == 'SunForm' ? '次级表格' : element.label,
    fieldId,
    type: element.componentType == 'SunForm' ? element.componentType : element.type,
    key: element.key,
    children,
  };
}
function getTableItemConfig(tableName: string, element) {
  let isSaveTable = false; //组件是否存表
  if (element.type === 'input' && element.componentProps.isSave) {
    isSaveTable = true;
  }

  if (element.componentType == 'SunForm') return getTableConfig(element, tableName);
  return {
    required: true,
    view: true,
    edit: true,
    disabled: false,
    isSubTable: false,
    isSaveTable,
    showChildren: false,
    tableName: tableName,
    fieldName: element.title,
    fieldId: element.dataIndex,
    type: element.type || element.componentType,
    key: element.key,
    children: [],
  };
}

// 辅助设置表单Disabled
export function changeSchemaDisabled(schemas, disabled?) {
  const layoutComponents = ['tab', 'grid', 'card'];
  schemas?.map((info) => {
    if (layoutComponents.includes(info.type!)) {
      info.children?.map((childInfo) => {
        childInfo.list.map((com) => {
          if (layoutComponents.includes(com.type) || com.type === 'table-layout') {
            changeSchemaDisabled(childInfo.list, disabled);
          } else {
            com.dynamicDisabled = disabled === false ? false : true;
          }
        });
      });
    } else if (info.type == 'table-layout') {
      info.children?.map((childInfo) => {
        childInfo.list.map((com) => {
          com.children.map((el) => {
            if (layoutComponents.includes(el.type) || el.type == 'table-layout') {
              changeSchemaDisabled(com.children, disabled);
            } else {
              el.dynamicDisabled = disabled === false ? false : true;
            }
          });
        });
      });
    } else if (info.type == 'one-for-one') {
      changeSchemaDisabled(info.componentProps.childSchemas, disabled);
      info.dynamicDisabled = disabled === false ? false : true;
    } else {
      info.dynamicDisabled = disabled === false ? false : true;
    }
  });
  return schemas;
}
