import React, { useState } from 'react';
import { message } from 'antd';
import { widgetData } from '../constant'

export function downloadFunc(url, name, target = '_self') {
  const a = document.createElement('a');
  a.href = url;
  a.target = target;
  a.download = name;
  a.click();
  a.remove();
}

/**
 *  @Description: 校验文件的名称是否包含特殊字符
 *  @Params: {Object: File} file file对象 { special:Boolean } 是否去除/的匹配
 *  @Date: 2021/12/8
 *  @Author: ChenLong
 *  @Return {Object} {type: error | success ,content: 提示...}
 * */
export function filenameVerification(file, special) {
  // 文件名含有特殊字符  提示不能上传   {+,:/?#[]@!$&\\*+;=}
  // 规则对象(flag)
  var flag = !special ? new RegExp('[`~!@#$^&*=|{}\':;\',\\[\\]/?~!@#¥&*——|{}【】‘;:”“\'。,、?]') : new RegExp('[`~!@#$^&*=|{}\':;\',\\[\\]?~!@#¥&*——|{}【】‘;:”“\'。,、?]');
  if (flag.test(file.name)) {
    return {
      type: 'error',
      content: `文件名格式错误,请检查文件名是否含有特殊字符${'~!@#$^&*=|{}\':;\',\\[\\]/?~!@#¥&*——|{}【】‘;:”“\'。,、?'}`,
    };
  }
  return {
    type: 'success',
    content: `上传成功!`,
  };
}

export const convertUrlToBase64 = async (url) => {
  const response = await fetch(url)
  const blob = await response.blob()
  return await new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => {
      const base64 = reader.result.split(',')[1]
      resolve(`data:image/svg+xml;base64,${base64}`)
    }
    reader.onerror = reject
    reader.readAsDataURL(blob)
  })
}

/**
 *  @Description: 判断数据类型
 *  @Params: 参数描述
 *  @Date: 2021/12/17
 *  @Author: ChenLong
 *  @Return: '[object 各自对相应的类型]','[object Function]', '[object Object]', '[object Array]', '[object String]', '[object Number]', '[object Boolean]', '[object Undefined]', '[object Null]', '[object Date]'
 * */
export function returnDataType(data) {
  return Object.prototype.toString.call(data);
}

export function parseSQL2JSON(str) {
  let finalArray = [];
  // 1.支持以下字符, > < 都包含等于
  // 2.关键字和关键字符必须前后空格
  // 3.仅支持单个关键字或者关键字符的筛选条件

  let queryWhere = [];

  /** @Tips: 台账名和字段的逻辑 */
  // 1. 解析台账名.字段名[.n](资产台账.编码[.n]) 是表明加载的台账和台账选择器返回的字段名,并且需要验证该字段【不可为空】
  let strArray = str.split('?');
  let accountNameAndField = strArray[0];

  let accountArray = accountNameAndField.split('.');
  let accountName = accountArray[0]; // 台账
  let returnField = accountArray[1]; // 需要返回的字段
  queryWhere.push({
    field: returnField,
    type: '不等于',
    value: '',
  });
  let isMultiple = accountArray.includes('n'); // 是否多选
  /** @End: 台账解析结束 */

  let otherCondition = strArray[1];
  /** @Tips: 1. 判断是否多条件 and */
  let otherConditionArray = otherCondition.split('and').map(item => item.trim());
  /** @Tips: 2. 解析规则,判断是否有关键词并组成JSON */
  otherConditionArray.forEach(item => {

  });

  return {
    accountName,
    isMultiple,
    returnField,
    queryWheres: [],
  };
}

/**
 * @description 墨卡托转经纬度
 * @param {*} x 
 * @param {*} y 
 * @returns 
 */
export const mercatorToLngLat = (x, y) => {
  const EARTH_RAD = 6378137
  const radToAngle = (rad) => {
    return rad * (180 / Math.PI)
  }
  let lng = radToAngle(x) / EARTH_RAD
  let lat = radToAngle(2 * Math.atan(Math.exp(y / EARTH_RAD)) - Math.PI / 2)
  return [lng, lat]
}

/**
 * @description 经纬度转墨卡托
 * @param {*} x 
 * @param {*} y 
 * @returns 
 */
export const lngmkt = (poi) => {
  var mercator = {};
  var earthRad = 6378137.0;
  mercator.x = ((poi.lng * Math.PI) / 180) * earthRad;
  var a = (poi.lat * Math.PI) / 180;
  mercator.y = (earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
  return mercator; //[12727039.383734727, 3579066.6894065146
};

//判断是否为JSON字符串
export const isJson = (json) => {
  if (typeof json === 'string') {
    try {
      let obj = JSON.parse(json)
      if (typeof obj === 'object' && obj) {
        return true
      }
    } catch (e) {
      return false
    }
  }
  return false
}

export const isObject = (obj) => typeof obj === 'object'

export const isArray = (array) => Array.isArray(array) && array.length

//防抖
export const debounce = (fn) => {
  let t = null
  return function (e) {
    const context = this
    const args = arguments
    if (t) {
      clearTimeout(t)
    }
    t = setTimeout(function () {
      if (typeof fn === 'function') {
        fn.call(context, ...args)
      }
    }, 300)
  }
}

//生成随机ID
export function getNanoid(len = 6, left = '分组名称_') {
  var orgStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let returnStr = "";
  for (var i = 0; i < len; i++) {
    returnStr += orgStr.charAt(Math.floor((Math.random() * orgStr.length)));
  }
  return `${left}${returnStr}`
}

//手动校验配置信息
export const getVerify = (json) => {
  if (isObject(json)) {
    let properties = json?.properties
    if (isObject(properties)) {
      for (let v in properties) {
        let child = properties[v]?.properties
        if (isObject(child)) {
          for (let s in child) {
            const { widget, sourceType, options, dictionary, tableName, fieldName, fieldParent, accountName, fieldshine } = child[s]
            if (['ComboBox', 'RadioButton', 'CheckBox'].includes(widget)) {
              if (sourceType === '手动输入' && !options.length) {
                return message.error(`字段【${s}】配置,选项值必填!`)
              }
              if (sourceType === '数据字典' && !dictionary) {
                return message.error(`字段【${s}】配置,数据字典必填!`)
              }
              if (sourceType === '表数据' && !tableName && !fieldName) {
                return message.error(`字段【${s}】配置,表名与字段名必填!`)
              }
            }
            if (['RelationForm'].includes(widget)) {
              if (!child[s]['映射字段'].length || !child[s]['台账名称']) {
                return message.error(`字段【${s}】配置,台账名称与映射字段必填!`)
              }
            }
            if (['RelevanceSelect'].includes(widget)) {
              if (!fieldParent || !dictionary) {
                return message.error(`字段【${s}】配置,父字段名与数据字典必填!`)
              }
            }
            if (['AccountSelector'].includes(widget)) {
              if (!accountName || !fieldshine) {
                return message.error(`字段【${s}】配置,台账名称与映射字段必填!`)
              }
            }
          }
        }
      }
    }
  }
  return true
}

const getWidgetSetting = (type, { title, tableName, tableType }) => {
  if (type === '日期') {
    return {
      title: title,
      "type": "string",
      "widget": "DateTime",
      "placeholder": "请选择日期",
      tableNameParent: tableName,
      tableTypeParent: tableType,
      "required": false,
      "disabled": false,
      "format": "date",
      "options": "默认为空",
      "groupStyle": {},
      "labelWidth": 110
    }
  } else if (type === '数值') {
    return {
      title: title,
      "type": "string",
      "widget": "NumberInput",
      "presetValue": "0",
      "placeholder": "请输入内容",
      tableNameParent: tableName,
      tableTypeParent: tableType,
      "rules": [],
      "required": false,
      "disabled": false,
      "groupStyle": {},
      "labelWidth": 110,
      "IsSystemField": false
    }
  }
  return {
    title: title,
    "type": "string",
    "widget": "TextInput",
    "placeholder": "请输入内容",
    tableNameParent: tableName,
    tableTypeParent: tableType,
    "maxLength": 200,
    "rules": [],
    "uniqueVerify": null,
    "required": false,
    "disabled": false,
    "isStoreID": false,
    "isQRCode": false,
    "groupStyle": {},
    "labelWidth": 110
  }
}

//将字段设置
export const setFieldJson = (json, fieldName) => {
  let properties = json?.properties
  let keys = []
  let parent = {}
  let extaObj = {}
  Object.keys(properties).forEach(v => {
    parent[v] = properties[v]
    let child = properties[v]?.properties
    if (isObject(child)) {
      Object.keys(child).forEach(s => {
        keys.push(s)
      })
    }
  })
  fieldName.forEach(j => {
    if (!keys.includes(j.name)) {
      extaObj[j.name] = getWidgetSetting(j.shapeTip, { ...json, title: j.name })
    }
  })
  if (JSON.stringify(extaObj) !== '{}') {
    parent[getNanoid()] = {
      title: '(未分组)',
      type: "object",
      collapsed: false,
      properties: extaObj
    }
  }
  return {
    ...json,
    properties: parent,
  }
}

//字段名对应的形态
export const getFieldInfo = (formJson) => {
  let obj = {}
  let parent = formJson?.properties
  if (isObject(parent)) {
    for (let v in parent) {
      let child = parent[v]?.properties
      if (isObject(child)) {
        for (let s in child) {
          obj[s] = { ...child[s], ...widgetData[child?.[s]?.widget] }
        }
      }
    }
  }
  return obj
}