import {DIM_TYPE_ENUM} from "../constants";
import {message} from "antd";

export function useModelConfig() {
  /**
   * 校验SELECT *
   * */
  function checkSelectAll(sql) {
    let flag = false;
    try {
      const parts = sql.split(/from/i);
      if (parts.length > 1) {
        const selectPart = parts[0];
        const fields = selectPart.split(",");
        if (fields.length > 1){
          fields.forEach(field=>{
            if (!flag){
              if (field.includes('*')){
                const regex = /[\w\W]*\([\w\W]*\*[\w\W]*\)[\w\W]*/
                if (!regex.test(field)){
                  flag = true
                }
              }
            }
          })
        }else {
          return sql.includes('*')
        }
      }
    }catch(e){}
    return flag;
  }

  /**
   * SQL字符串格式化为字段数组
   * {
   *   table : 表名
   *   field : 字段
   *   alias : 别名
   * }
   * */
  const toFields = (sql) => {
    try {
      const regexf = /from/i;                         // 匹配FROM的规则
      const regexas = /\s+AS\s+/i;                    // 匹配AS的规则
      const regexs = /select/gi;                      // 匹配SELECT的规则
      const regext = /FROM\s+([\w]+)/i;               // 匹配表名的规则
      const regexc =  /[^,]*\([^)]*\) AS [^,]*/gi;    // 匹配复合字段规则 如 CONVERT(admDate,datetime) as admDate,  CAST(admDate AS DATE) as admDate2,
      const regexcs = /\)\s+as\s+([\w]+)/i;           // 取admDate/admDate2
      const regexjoin = /\b(LEFT\s+JOIN|RIGHT\s+JOIN|INNER\s+JOIN)\b/i; // 匹配JOIN的规则

      // 取SELECT-FROM之间的字符串，并分割出所有字段
      const matchf = sql.match(regexf);
      const fromIndex = matchf?.index || 0;
      let matchcStr = sql.slice(0, fromIndex).replace(regexs,'');

      // 匹配COUNT()类型的字段，摘取出来单独处理
      const matchc = matchcStr.match(regexc);
      let fieldc = [];
      if (matchc){
        matchcStr = matchcStr.replace(regexc, '');
        fieldc = matchc.map(c=>c.match(regexcs)[1]);
      }

      // 按逗号分割字段
      const fieldArr = matchcStr.split(',');
      // 截取form之后的字符串
      const sqlRelation = sql.slice(fromIndex);
      // 判断是否有JOIN
      const isJoin = regexjoin.test(sqlRelation.toUpperCase());
      // 单表查询直接取表名
      const matchStr = sqlRelation.match(regext);
      const singleTable = ( matchStr && matchStr[1] ) || "";

      // 按顺序处理SQL字符串
      return fieldArr.concat(fieldc).map(item=> {
        let str=item,table=singleTable,field,aliasStr;
        // 判断字符串是否包含AS,有则去除AS
        const hasAs = regexas.test(item);
        if (hasAs){
          const asStr = item.match(regexas)[0];
          str = item.split(asStr)[0];
          aliasStr = item.split(asStr)[1].trim();
        }
        // 去除AS之后去除所有符号,但不包含'.'
        str = str.replaceAll(/^\s+|\s+$/g, '').replaceAll(/\s+/g, '');

        // 若是以.的形式取则分割出表和字段
        if (str.includes('.')){
          const split = str.split('.');
          table = split[0]
          field = split[1]
        }

        // 有join则按表分类字段，否则直接取FROM后面的表
        return isJoin
          ? {table,field,alias:aliasStr}
          : {
            table:table?table:singleTable,
            field:field?field:str,
            alias:aliasStr
          }
      });
    }catch(e){
      return []
    }
  }

  /**
   * SQL模型初始化
   *  1.将接口返回的模型字段（fields）重新拼接为SQL
   *  2.返回一个初始化表格数据
   * @param model 模型名称
   * @param sql 模型的sql字符串
   * @param fields 模型包含的字段
   * @param bizs  fields的字段类型配置
   * */
  const initSqlModel=(model,sql,fields,bizs)=>{
    let tableData = [];
    try {
      const regex1 = /from/i;
      const match = sql.match(regex1);
      const fromIndex = match?.index || 0;
      const sqlRelation = sql.slice(fromIndex);
      let SQLFields = "SELECT \r\n"
      fields.forEach(({bizName,tableName,fieldName,dataType,comment},index) => {
        // 是否最后一个
        const isLast = index===fields.length-1
        SQLFields += `\t${tableName}.${fieldName}${!isLast&&","}\r\n`
        const initObj = bizs.find(item=>item.name===fieldName);
        tableData.push({
          id:Math.random(),
          comment:comment,
          bizName: bizName.replace(model+"_",""),
          dataType: dataType,
          fieldName: fieldName,
          tableName: tableName,
          isKey:DIM_TYPE_ENUM.IDENTIFY===initObj?.type,
          common:DIM_TYPE_ENUM.CATEGORICAL===initObj?.type,
          datetime:DIM_TYPE_ENUM.DATETIME===initObj?.type,
          measure:!initObj?.type,
        })
      })
      return {
        tableData,
        sql:SQLFields+sqlRelation,
      }
    }catch (e) {
      return {
        tableData:[],
        sql:"",
      }
    }
  }

  /**
   * SQL模型初始化
   *  1.将接口返回的模型字段（fields）重新拼接为SQL
   *  2.返回一个初始化表格数据
   * @param model 模型名称
   * @param columns 执行SQL语句后返回的表头
   * @param fields SQL字符串转换的字段
   * @param init  模型字段初始信息
   * @param bizs  模型字段的维度、度量
   * */
  const sqlResultToTable = (model,columns,fields,init,bizs) => {
    try {
      let tableData = [];
      columns.forEach(col=>{
        // SQL中摘出的字段、别名、表
        let table="";
        let alias="";
        let field="";
        const findField = fields.find(item=>item.field===col.nameEn || item.alias===col.nameEn);
        if (!findField){
          return false
        }
        table = findField.table
        alias = findField.alias
        field = findField.field

        // 校验两个字段是否重叠
        const exist = tableData.find(item=>item.tableName===table && item.fieldName===col.nameEn)
        if (exist){
          // 若重叠
          const field = fields
            .filter(item=>!(item.table===table && item.field===col.nameEn))
            .find(item=>item.field===col.nameEn)

          table = field?.table || '';
          alias = field?.alias || '';
        }

        // 描述能取初始值就取初始值
        const finalField = alias?field:col.nameEn;
        let mergeObj ;
        if (init.length>0){
          mergeObj = init.find(item=> item.tableName === table && item.fieldName === finalField)
        }

        // 初始化配置
        const initObj = bizs.find(item=>item.name===finalField);
        // 字段：有别名取字段否则取返回的值
        tableData.push(
          {
            id:Math.random(),
            bizName: alias? alias: (mergeObj? mergeObj?.bizName.replace(model+"_",""):finalField),
            comment: mergeObj? mergeObj?.comment : col.comment,
            dataType: col.type,
            fieldName: finalField,
            tableName: table,
            isKey:DIM_TYPE_ENUM.IDENTIFY===initObj?.type,
            common:DIM_TYPE_ENUM.CATEGORICAL===initObj?.type,
            datetime:DIM_TYPE_ENUM.DATETIME===initObj?.type,
            measure:bizs.length>0 && !initObj?.type
          }
        )
      })
      return tableData
    }catch (e) {
      return false
    }
  }

  /**
   * SQL字段数据 格式化为 表格数据
   * @param table 表名
   * @param fields 字段数组
   * */
  const fieldsToTable=(table,fields)=>{
    try {
      return fields.map(field=>({
        id:Math.random(),
        bizName: field?.nameEn,
        comment: field?.comment,
        dataType: field?.type,
        fieldName: field?.nameEn,
        tableName: table,
        isKey:false,
        common:false,
        datetime:false,
        measure:false,
      }))
    }catch (e) {
      return []
    }
  }


  /**
   * 快速创建模型初始化
   *  1.返回一个初始化表格数据
   * @param model 模型名称
   * @param nodes 节点数据
   * @param dimensions 维度数据
   * @param bizs  模型字段的维度、度量的初始配置
   * */
  const initQuickModel=(model,nodes,dimensions,bizs)=>{
    let tableData = [];
    try {
      // 插入模型维度
      nodes.forEach(field => {
        const initObj = bizs.find(item=>item.name===field.fieldName)
        if (initObj){
          tableData.push({
            ...field,
            id:Math.random(),
            bizName:initObj.bizName.replace(model+"_", ""),
            isKey:DIM_TYPE_ENUM.IDENTIFY===initObj.type,
            common:DIM_TYPE_ENUM.CATEGORICAL===initObj.type,
            datetime:DIM_TYPE_ENUM.DATETIME===initObj.type,
            measure:!initObj.type,
          });
        }else {
          tableData.push(field)
        }
      })

      // 插入自定义的维度
      const insertDims = (dimensions||[]).filter(item=>
        nodes.findIndex(field=> field.fieldName===item.name)<0
      );

      insertDims.forEach(field=>{
        tableData.push({
          ...field,
          id:Math.random(),
          bizName:field.name,
          isKey:DIM_TYPE_ENUM.IDENTIFY===field.type,
          common:DIM_TYPE_ENUM.CATEGORICAL===field.type,
          datetime:DIM_TYPE_ENUM.DATETIME===field.type,
          measure:false,
          comment:field.description,
          disabled:true,
          fieldName: '自定义',
          tableName: '自定义',
        })
      })
    }catch (error) {
      message.error('维度初始化失败：'+error)
    }
    return tableData
  }


  return {
    toFields,
    initSqlModel,
    initQuickModel,
    checkSelectAll,
    sqlResultToTable,
    fieldsToTable
  }
}