import axios from 'axios'
import JsZip from 'jszip'

const noWmpl: string[] = ['Document', 'Folder', 'Placemark', 'Point', 'coordinates']

/**
 * @description: 读取kmz文件解析出kml文件
 * @param {string} filePath 文件地址
 * @return {*}
 */
export const analyzeKmzFile = (filePath: string) => {
  return axios
    .get(filePath, { responseType: 'arraybuffer' })
    .then((fileRes) => fileRes.data)
    .then((kmzData) => JsZip.loadAsync(kmzData)) // 解压kmz文件
    .then((zipFile) => {
      const files: { [key: string]: Promise<string> } = {}
      Object.keys(zipFile.files).forEach((key: string) => {
        files[key] = zipFile.files[key].async('text')
      })
      return {
        zip: zipFile,
        fileInfoObj: files,
      }
    })
}

export const getKmlParams = (
  source: string,
  isWpml: boolean,
  params: { name: string | undefined; findRegx: string; mode?: string },
) => {
  let regx = null
  if (isWpml) {
    if (params.mode) {
      regx = new RegExp(`<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`, params.mode)
    } else {
      regx = new RegExp(`<wpml:${params.name}>${params.findRegx}<\\/wpml:${params.name}>`)
    }
  } else {
    if (params.mode) {
      regx = new RegExp(`<${params.name}>${params.findRegx}<\\/${params.name}>`, params.mode)
    } else {
      regx = new RegExp(`<${params.name}>${params.findRegx}<\\/${params.name}>`)
    }
  }
  return source?.match(regx)
}

export const generateKmlFormat = (settingParmas: any) => {
  let paramGroup = ''
  Object.keys(settingParmas).forEach((key: string) => {
    if (Object.prototype.toString.call(settingParmas[key]) === '[object Object]') {
      let parmaStr = ''
      Object.keys(settingParmas[key]).forEach((v) => {
        const xml = noWmpl.includes(key)
          ? `<${v}>${settingParmas[key][v]}</${v}>`
          : `<wpml:${v}>${settingParmas[key][v]}</wpml:${v}>`
        parmaStr += xml
      })
      const xml = noWmpl.includes(key) ? `<${key}>${parmaStr}</${key}>` : `<wpml:${key}>${parmaStr}</wpml:${key}>`
      paramGroup += xml
    } else {
      const xml = noWmpl.includes(key)
        ? `<${key}>${settingParmas[key]}</${key}>`
        : `<wpml:${key}>${settingParmas[key]}</wpml:${key}>`
      paramGroup += xml
    }
  })
  return paramGroup
}

export const getTagNameFromXml = (xmlString: string): string | null => {
  const parser = new DOMParser()
  const xmlDoc = parser.parseFromString(xmlString, 'text/xml')
  const element = xmlDoc.documentElement
  if (element && element.tagName) {
    return element.tagName // 返回的是类似 "WPML:USEGLOBALHEADINGPARAM" 的全大写形式
  }
  return null
}

// 将xml转为json
const deepParse = (
  xml:
    | {
        nodeType: number
        childNodes: string | any[]
        nodeValue: string
        attributes: { length: number; item: (arg0: number) => any }
      }
    | any,
) => {
  let obj: any = {}
  // 如果是文档节点，遍历其子节点
  if (xml.nodeType === 1) {
    // element node
    // 处理子节点
    if (xml.childNodes.length > 0) {
      for (let i = 0; i < xml.childNodes.length; i++) {
        const item = xml.childNodes[i]
        const nodeName = item.nodeName.replace('wpml:', '')

        // 检查是否是文本节点
        if (item.nodeType === 3) {
          // text node
          // 处理文本节点的内容
          if (item.nodeValue.trim() !== '') {
            obj[nodeName] = item.nodeValue.trim()
          }
        } else if (item.nodeType === 1) {
          // element node
          // 递归调用处理子节点
          if (obj[nodeName] === undefined) {
            const nodeValue = deepParse(item)
            if (nodeValue[nodeName] === undefined) {
              obj[nodeName] = nodeValue
            } else {
              obj[nodeName] = nodeValue[nodeName]
            }
          } else {
            if (!obj[nodeName].push) {
              const old = obj[nodeName]
              obj[nodeName] = []
              obj[nodeName].push(old)
            }
            const nodeValue = deepParse(item)
            if (nodeValue[nodeName] === undefined) {
              obj[nodeName].push(nodeValue)
            }
          }
        }
      }
    }
  } else if (xml.nodeType === 3) {
    // text node
    // 处理文本节点的内容
    obj = xml.nodeValue.trim()
  }
  return obj
}

/**
 * @description: XML转JSON
 * @param {string} xmlStr xml字符串
 * @return {*} string
 */
export const XMLToJSON = (xmlStr: string) => {
  const parser = new DOMParser()
  const xmlDoc = parser.parseFromString(xmlStr, 'text/xml')
  const xmlObj = deepParse(xmlDoc.documentElement)
  if (Reflect.has(xmlObj, 'Document')) {
    return xmlObj
  } else {
    return {
      Document: xmlObj,
    }
  }
}

// json转xml
/**
 * @description: JSON转XML
 * @param {any} obj 要转换的对象
 * @param {string} rootName xml根节点名称
 * @return {*} string
 */
export const JSONToXML = (obj: any, rootName?: string | undefined, isEnd: boolean = false) => {
  let xml = ''

  const buildXml = (obj: string | any[], rootName: string = '') => {
    let xml = ''
    if (Array.isArray(obj)) {
      obj.forEach((item) => {
        const str = !noWmpl.includes(rootName) && isEnd ? 'wpml:' : ''
        xml += `<${str}${rootName}>${buildXml(item)}</${str}${rootName}>`
      })
    } else if (typeof obj === 'object') {
      Object.keys(obj).forEach((key) => {
        if (key === '#text') {
          xml += obj[key]
        } else {
          const str = !noWmpl.includes(key) && isEnd ? 'wpml:' : ''
          if (key === 'Placemark') {
            xml += `${buildXml(obj[key], key)}`
          } else {
            xml += `<${str}${key}>${buildXml(obj[key], key)}</${str}${key}>`
          }
        }
      })
    } else {
      xml += obj
    }
    return xml
  }

  const header = isEnd ? '<?xml version="1.0" encoding="UTF-8"?>' : ''
  xml += `${header}
  <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:wpml="http://www.dji.com/wpmz/1.0.5">
    <Document>
      ${buildXml(obj, rootName)}
    </Document>
  </kml>`
  return xml
}
