import Pinyin from 'js-pinyin'; //将汉字转为拼音
Pinyin.setOptions({ charCase: 1 });
import { requestMagicApi } from '/@/api/magicApi';
import { useUserStore } from '/@/store/modules/user';
import { BasicColumn } from '/@/components/Table';
import { isNil } from 'lodash-es';
import opencc from 'node-opencc';
import { TableFieldConfig } from '/@/model/generator/tableStructureConfig';
import { MessageSend } from '/@/api/workflow/task';
import { MemberType } from '/@/enums/workflowEnum';
import nzhcn from 'nzh/cn';
import { getUserMulti } from '/@/api/system/user';
import { getAppEnvConfig } from '/@/utils/env';

//setOptions中传入对象，对象可传两个参数
//charCase： 输出拼音的大小写模式，0-首字母大写；1-全小写；2-全大写
//checkPolyphone：是否检查多音字
//方法：1.getCamelChars: 获取拼音首字母  2.getFullChars: 获取拼音

/* 判断字符串是否有中文 有则在前面添加下划线（第一个字符不添加）并转换成小写拼音 */
export function changeToPinyin(label: string, isUpper?: boolean) {
  const labelArr = label.split('');
  let fieldName = '';
  labelArr.map((item: string, index: number) => {
    const reg = /^[\u4e00-\u9fa5]+$/;
    item = opencc.traditionalToSimplified(item);
    fieldName += reg.test(item) && index !== 0 ? '_' + item : item;
  });
  const pinyin = Pinyin.getFullChars(fieldName.replace(/\s+/g, ''));
  return isUpper ? pinyin.toUpperCase() : pinyin;
}

/* 如果没有下划线，不需要处理
如果有下划线，用下划线切割，第一个下划线左边的全部小写，后面的首字母大写，首字母后面的全部小写 */
export function camelCaseString(string: string, islowerCase = true) {
  if (!string) return;
  if (string.indexOf('_') < 0 && islowerCase) return string;
  const stringLower = islowerCase ? string.toLowerCase() : string;
  const len = stringLower.length;
  let str = '';
  for (let i = 0; i < len; i++) {
    const c = stringLower.charAt(i);
    if (c === '_') {
      if (++i < len) {
        str = str.concat(stringLower.charAt(i).toUpperCase());
      }
    } else {
      str = str.concat(c);
    }
  }
  return str;
}

let isJsonData = false;

export async function apiConfigFunc(
  apiConfig,
  isCustomForm = false,
  formModel?,
  index?,
  page?,
  parentIndex?,
) {
  if (!apiConfig?.path) return [];
  const queryParam = {};
  const headerParam = {};
  const bodyParam = {};
  if (apiConfig?.apiParams) {
    for (const param of apiConfig.apiParams) {
      //queryString
      if (param.key === '1' && param.tableInfo && param.tableInfo.length) {
        for (const query of param.tableInfo) {
          if (page?.current && query.name == 'limit') {
            query.value = page.current;
          }
          if (page?.pageSize && query.name == 'size') {
            query.value = page.pageSize;
          }
          if (page?.order && query.name == 'order') {
            query.value = page.order;
          }
          if (page?.order && query.name == 'field') {
            const obj = param.tableInfo.find(
              (o) => o.bindType == 'data' && o.value.includes(page.field),
            );
            if (obj) query.value = obj.name;
          }

          queryParam[query.name] = getParamsValue(
            query,
            formModel,
            isCustomForm,
            index,
            false,
            parentIndex,
          );
        }
      }
      //header
      if (param.key === '2' && param.tableInfo && param.tableInfo.length) {
        for (const head of param.tableInfo) {
          headerParam[head.name] = getParamsValue(
            head,
            formModel,
            isCustomForm,
            index,
            true,
            parentIndex,
          );
        }
      }
      //body
      if (param.key === '3' && param.tableInfo && param.tableInfo.length) {
        for (const body of param.tableInfo) {
          bodyParam[body.name] = getParamsValue(
            body,
            formModel,
            isCustomForm,
            index,
            false,
            parentIndex,
          );
          console.log('formModel', formModel, bodyParam);
        }
      }
    }
  }
  const obj: any = {
    method: apiConfig?.method,
    url: apiConfig.path,
    headers: headerParam,
    query: queryParam,
  };
  if (isJsonData || Object.keys(bodyParam).length > 0) {
    headerParam['Content-Type'] = 'application/json';
    obj.body = JSON.stringify(bodyParam);
  }

  const res = await requestMagicApi(obj);
  if (res && Array.isArray(res)) return res; //不分页接口
  if (res && Array.isArray(res.list)) {
    if (page) {
      page.total = res.total;
    }
    return res.list;
  } //分页接口
  return res;
}

function getParamsValue(
  params,
  formModel,
  isCustomForm,
  index,
  isHeaders: Boolean = false,
  parentIndex,
) {
  const userStore = useUserStore();
  let value;
  if (params.bindType === 'data') {
    const paramsArr = params.value.split('-');
    if (paramsArr[0] === '3') {
      //当前信息
      value = isHeaders
        ? encodeURIComponent(userStore.getUserInfo[paramsArr[1]])
        : userStore.getUserInfo[paramsArr[1]];
    } else {
      if (!formModel) return;
      let headerValue;
      if (params.value) {
        const value = isValidJSON(params.value);
        if (params.type === 'form') {
          isJsonData = true;
          const table = !isCustomForm
            ? params.value + 'List'
            : camelCaseString(params.value + '_List');
          const fieldObj = {};
          params.children.forEach((child) => {
            const field = child.value.split(',')[1];
            fieldObj[child.name] = !isCustomForm ? field : camelCaseString(field);
          });
          headerValue = [];
          console.log('formModel', formModel, table, formModel[table!]);
          if (formModel[table!]?.length) {
            formModel[table!].forEach((sub) => {
              const subformModel = {};
              for (const key in fieldObj) {
                subformModel[key] = sub[fieldObj[key]];
              }
              headerValue.push(subformModel);
            });
          }
        } else if (value && value.bindTable) {
          const parentTable = value.parentTable
            ? !isCustomForm
              ? value.parentTable + 'List'
              : camelCaseString(value.parentTable + '_List')
            : null;
          const table = !isCustomForm
            ? value.bindTable + 'List'
            : camelCaseString(value.bindTable + '_List');
          const field = !isCustomForm ? value.bindField : camelCaseString(value.bindField);
          if (parentTable && formModel[parentTable] && formModel[parentTable][parentIndex]) {
            if (
              formModel[parentTable][parentIndex][table!] &&
              formModel[parentTable][parentIndex][table!][index || 0]
            ) {
              headerValue = formModel[parentTable][parentIndex][table!][index || 0][field];
            }
          } else if (formModel[table!] && formModel[table!][index || 0]) {
            headerValue = formModel[table!][index || 0][field];
          }
        } else {
          if (Array.isArray(formModel)) {
            headerValue = formModel.map((item) =>
              !isCustomForm ? item[value.bindField!] : item[camelCaseString(value.bindField)!],
            );
          } else {
            headerValue = !isCustomForm
              ? formModel[value.bindField!]
              : formModel[camelCaseString(value.bindField)!];
          }
        }
      }

      value = isHeaders ? encodeURIComponent(headerValue) : headerValue;
    }
  } else {
    value = params.value;
  }
  return value;
}
export function isValidJSON(str) {
  try {
    const val = JSON.parse(str);
    return val;
  } catch (err) {
    return false;
  }
}

/**
 * 根据列表值 生成table html
 */
export function generateTableHtml(columns: BasicColumn[], datas: Recordable[]): string {
  const headArray: {
    key: string;
    name: string;
  }[] = [];
  const bodySortArray: string[][] = [];

  let result = `<table>`;

  result += `<tr>`;
  //遍历所有列配置 设置为表头
  for (const col of columns) {
    if (col.dataIndex) {
      headArray.push({
        key: col.dataIndex as string,
        name: col.title as string,
      });
    }
    result += `<th>${col.title}</th>`;
  }
  result += `</tr>`;
  //遍历所有数据

  for (const item of datas) {
    result += `<tr>`;
    const row: string[] = [];
    for (const head of headArray) {
      const index = Object.keys(item).indexOf(head.key);
      row[index] = item[head.key];
      result += `<td>${item[head.key]}</td>`;
    }
    bodySortArray.push(row);
    result += `</tr>`;
  }

  result += '</table>';
  return result;
}

/**
 * 根据列表值 生成table html
 */
export function generateTableJson(columns: BasicColumn[], datasource: Recordable[]): Recordable[] {
  const result: Recordable[] = [];

  for (const item of datasource) {
    //替换所有key
    const newRow: Recordable = {};
    Object.keys(item).forEach((key) => {
      const col = columns.find((x) => x.dataIndex == key);
      if (col?.title) {
        if (col?.staticOptions && !isNil(item[key])) {
          if (col?.componentType === 'checkbox') {
            const seleted = col?.staticOptions.filter((opt) => {
              const valueArr = item[key].split(',');
              return valueArr.includes(opt.value);
            });
            newRow[col?.title as string] = seleted.map((sel) => sel.label).toString();
          } else {
            const seleted = col?.staticOptions.find((opt) => opt.value === item[key]);
            newRow[col?.title as string] = seleted?.label || '';
          }
        } else {
          newRow[col?.title as string] = isNil(item[key]) ? '' : item[key];
        }
      }
    });
    result.push(newRow);
  }

  return result;
}

export function checkTabCanDelete(layout) {
  let count = 0;
  for (let i = 0; i < layout.length; i++) {
    const o = layout[i];
    for (let i = 0; i < o.list.length; i++) {
      const k = o.list[i];
      if (k.type == 'form' || k.type == 'one-for-one') {
        count += 1;
        break;
      } else if (k.type == 'tab' || k.type == 'card' || k.type == 'grid') {
        count = checkTabCanDelete(k.layout);
        if (count > 0) break;
      } else if (k.options?.required) {
        count += 1;
        break;
      }
    }
    if (count > 0) break;
  }
  return count;
}
const needDicDefaultValue = [
  'select',
  'associate-select',
  'associate-popup',
  'multiple-popup',
  'checkbox',
  'radio',
  'button',
];
export function changeCompsApiConfig(list, designType, TableFieldConfigs) {
  list.forEach((item) => {
    if (needDicDefaultValue.includes(item.type)) {
      //主表
      if (
        item.type == 'button' &&
        item.options.isSpecial &&
        item.options.buttonType == 2 &&
        designType !== 'data'
      ) {
        changeTableColumns(item.options.tableColumns, TableFieldConfigs);
      }
      if (item.options?.datasourceType == 'api') {
        changeApiParams(item.options.apiConfig.apiParams, designType, TableFieldConfigs);
        changeOutputParams(item.options.apiConfig.outputParams, designType, TableFieldConfigs);
      } else if (item.options?.datasourceType == 'dic') {
        changeDicOptions(item.options.dicOptions, designType, TableFieldConfigs);
      }
    } else if (item.type == 'computational' || item.type == 'money-chinese') {
      item.options.computationalConfig.forEach((o) => {
        if (o.bindField && o.bindTable) {
          const comp = TableFieldConfigs.find((k) => k.key == o.key);
          if (comp) {
            o.bindField = comp.fieldName;
            o.bindTable = comp.tableName;
          }
        }
      });
    } else if (item.type == 'modal' || item.type == 'drawer') {
      item.options.innerParams.forEach((o) => {
        if (o.type == 'form') {
          const value = isValidJSON(o.value);
          if (value && value.key) {
            const comp = TableFieldConfigs.find((k) => k.key == value.key);
            if (comp) {
              value.field = comp.fieldName;
              value.table = comp.tableName;
              o.value = JSON.stringify(value);
            }
          }
        }
      });
      item.options.outParams.forEach((o) => {
        const value = isValidJSON(o.mainComponent);
        if (value && value.key) {
          const comp = TableFieldConfigs.find((k) => k.key == value.key);
          if (comp) {
            value.field = comp.fieldName;
            value.table = comp.tableName;
            o.value = JSON.stringify(value);
          }
        }
      });
    } else if (['tab', 'grid', 'card'].includes(item.type)) {
      for (const child of item.layout!) {
        changeCompsApiConfig(child.list, designType, TableFieldConfigs);
      }
    } else if (item.type === 'table-layout') {
      for (const child of item.layout!) {
        for (const el of child.list) {
          changeCompsApiConfig(el.children, designType, TableFieldConfigs);
        }
      }
    } else if (item.type === 'one-for-one' || item.type === 'form') {
      if (item.children.length) {
        changeCompsApiConfig(item.children, designType, TableFieldConfigs);
      }
    }
  });
}
export function changeEventApiConfig(formEventConfig, designType, TableFieldConfigs) {
  for (const config in formEventConfig) {
    formEventConfig[config].forEach((item) => {
      if (item.isUserDefined) {
        item.nodeInfo.processEvent.forEach((o) => {
          if (o.operateType == 'api') {
            changeApiParams(o.operateConfig.apiParams, designType, TableFieldConfigs);
          }
        });
      }
    });
  }
}
function changeApiParams(apiparams, designType, TableFieldConfigs) {
  if (!apiparams) return;
  apiparams.forEach((param) => {
    param.tableInfo?.forEach((info) => {
      if (info.bindType == 'data') {
        if (info.value) {
          const paramsArr = info.value.split('-');
          if (paramsArr[0] === '3') return;
          const val = isValidJSON(info.value);
          if (designType == 'code') {
            if (val && val.bindField) {
              const comp = TableFieldConfigs.filter((o) => o.key == val.fieldKey);
              if (comp.length == 1) val.bindField = comp[0].fieldName;
              if (comp.length == 2) {
                const field = new Array(2);
                comp.forEach((o) => {
                  if (o.fieldStartName) field[0] = o.fieldStartName;
                  if (o.fieldEndName) field[1] = o.fieldEndName;
                });
                val.bindField = field.join(',');
              }
            }
          }
          if (designType !== 'data') {
            if (val && val.bindTable) {
              const comp = TableFieldConfigs.find((o) => o.key == val.fieldKey);
              if (comp) val.bindTable = comp.tableName;
            }
          }
          info.value = JSON.stringify(val);
        }
      }
    });
  });
}
function changeOutputParams(outputParams, designType, TableFieldConfigs) {
  if (designType == 'code' && outputParams) {
    outputParams.forEach((item) => {
      const comp = TableFieldConfigs.find((o) => o.key == item.component);
      if (comp) {
        item.bindField = comp.fieldName;
        if (item.bindTable) item.bindTable = comp.tableName;
      }
    });
  }
}
function changeDicOptions(dicOptions, designType, TableFieldConfigs) {
  if (designType == 'code' && dicOptions) {
    dicOptions.forEach((item) => {
      const comp = TableFieldConfigs.find((o) => o.key == item.component);
      if (comp) {
        item.bindField = comp.fieldName;
        if (item.bindTable) item.bindTable = comp.tableName;
      }
    });
  }
}
function changeTableColumns(tableColumns, TableFieldConfigs) {
  tableColumns &&
    tableColumns.forEach((item) => {
      const comp = TableFieldConfigs.find((o) => o.key == item.key);
      if (comp) {
        item.bindField = comp.fieldName;
        item.bindTable = comp.tableName;
      }
    });
}
export function getMainTable(tableStructureConfigs) {
  const TableFieldConfigs: TableFieldConfig[] = [];
  tableStructureConfigs?.forEach((x) => {
    x.tableFieldConfigs.forEach((o) => {
      o.tableName = x.tableName;
      TableFieldConfigs.push(o);
    });
  });
  return TableFieldConfigs;
}

export function testPwdState(pwd) {
  let score = 0;

  const pwdArr = pwd.split('');
  const numArr = pwdArr.filter((x) => /[0-9]/.test(x)); //数字数组
  const alpArr = pwdArr.filter((x) => /[a-z]/.test(x)); //小写字母数组
  const ALPArr = pwdArr.filter((x) => /[A-Z]/.test(x)); //大写字母数组
  const charArr = pwdArr.filter((x) => /[^a-zA-Z0-9]/.test(x)); //特殊字符数组

  if (pwd.length <= 4) {
    //小于等于4个字符
    score += 5;
  } else if (pwd.length >= 5 && pwd.length <= 7) {
    //5-7个字符
    score += 10;
  } else if (pwd.length > 8) {
    //8个字符以上
    score += 25;
  }

  if (alpArr.length === pwdArr.length || ALPArr.length === pwdArr.length) {
    //全部都是大写字母或者小写字母
    score += 10;
  } else if (alpArr.length && ALPArr.length) {
    //大小写混合
    score += 20;
  }

  if (numArr.length === 1) {
    //只有一个数字
    score += 10;
  } else if (numArr.length >= 3) {
    //大于等于3个数字
    score += 20;
  }

  if (charArr.length === 1) {
    //只有一个符号
    score += 10;
  } else if (charArr.length > 1) {
    //大于一个符号
    score += 25;
  }

  if (ALPArr.length && alpArr.length && numArr.length && charArr.length) {
    //含有大写字母、小写字母、数字、符号
    score += 5;
  } else if ((ALPArr.length || alpArr.length) && numArr.length && charArr.length) {
    //含有字母、数字、符号
    score += 3;
  } else if ((ALPArr.length || alpArr.length) && numArr.length) {
    //含有字母、数字
    score += 2;
  }

  return score;
}

export function validateScript(str) {
  if (str.indexOf('<script') !== -1) {
    throw new Error('参数错误');
  }
}

export function testRegLength(reg) {
  if (reg.length > 255) {
    throw new Error('字符长度超出255个字符');
  }
}

export async function pushMessageFunc(messageConfig, isCustomForm = false, formModel?, formId?) {
  const bodyParam = { ...messageConfig };
  bodyParam['formId'] = formId;
  if (messageConfig.configs) {
    bodyParam['config'] = [];
    for (let i = 0; i < messageConfig.configs.length; i++) {
      const element = messageConfig.configs[i];
      const value = await getMessageParamsValue(element, formModel, isCustomForm);
      bodyParam['config'].push({
        assignmentType: messageConfig.type,
        config: '',
        description: element.description,
        name: element.name,
        value: value,
      });
    }
    delete bodyParam.configs;
  }
  messageConfig.receiverConfiguration.forEach((element, index) => {
    if (
      element.memberType == MemberType.FORM_FIELD &&
      element.formFieldConfig &&
      element.formFieldConfig['formField']
    ) {
      const bindField = element.formFieldConfig['formField'];
      const field = !isCustomForm ? bindField : camelCaseString(bindField);
      bodyParam['receiverConfiguration'][index]['value'] = formModel[bindField]
        ? formModel[bindField]
        : formModel[field];
    }
  });
  try {
    const res = await MessageSend(bodyParam);
    return res;
  } catch (error) {
    return false;
  }
}

async function getMessageParamsValue(params, formModel, _isCustomForm) {
  let value = '';
  if (params.assignmentType === 'value') {
    value = params.value;
  } else if (params.assignmentType === 'formData') {
    if (!formModel) return;
    if (params.value) {
      const valueObj = JSON.parse(params.value);
      const field = !_isCustomForm ? valueObj.bindField : camelCaseString(valueObj.bindField);
      value = formModel[valueObj.bindField] ? formModel[valueObj.bindField] : formModel[field];
      if (valueObj.options?.type == 'info' || valueObj.options?.type == 'user') {
        const users = await getUserMulti(value);
        value = users.map((item) => item.name).toString();
      }
    }
  }
  return value;
}

export function moneyChineseData(value) {
  let listValue = '';
  if (!isNaN(value) && value !== null) {
    const valueArr = value.toString().split('.');
    const decimalsArr = valueArr.length > 1 ? valueArr[1].split('') : [];
    listValue = `${nzhcn.encodeB(valueArr[0])}元`;
    if (decimalsArr.length) {
      decimalsArr.forEach((num, idx) => {
        let unit = '';
        switch (idx) {
          case 0:
            unit = '角';
            break;
          case 1:
            unit = '分';
            break;
          case 2:
            unit = '厘';
            break;
          case 3:
            unit = '毫';
            break;
        }
        listValue = listValue.concat(nzhcn.encodeB(num) + unit);
      });
    }
  } else {
    listValue = '';
  }
  return listValue;
}

export function formatter(value, decimals) {
  if (isNil(decimals)) return value;
  const reg = new RegExp(`^(-)*(\\d+)\\.([\\d]{${decimals}}).*$`);
  return value.replace(/\B(?=(\d{3})+(?!\d))/g, '').replace(reg, '$1$2.$3');
}

export const alphabet = [
  'A',
  'B',
  'C',
  'D',
  'E',
  'F',
  'G',
  'H',
  'I',
  'J',
  'K',
  'L',
  'M',
  'N',
  'O',
  'P',
  'Q',
  'R',
  'S',
  'T',
  'U',
  'V',
  'W',
  'X',
  'Y',
  'Z',
];

export const getFileUrl = (file, url = 'fileUrl') => {
  if (!file) return '';
  if (file.isLocal && file[url]) {
    return getAppEnvConfig().VITE_GLOB_API_URL + file[url];
  }
  return file[url];
};
