//这个是基于ceisum的二开，所以有些api不大相同
// 区域划分的颜色配置
import regionResult from './regionTreeResult.json'

const CooGL = window.CooGL;

// 调试开关
const DEBUG = true;

const IS_PROD = process.env.NODE_ENV === 'production' ? true : false;

// API基础URL配置
const API_BASE_URLS = {
  // 直接地址
  DIRECT: {
    REGION_API: 'https://10.1.174.34:13600/kelan/api',
    GRID_RANGE_API: 'https://10.1.174.34:13600/grid-range'
  },
  // 相对地址（代理）
  PROXY: {
    REGION_API: IS_PROD?'/cd-comprehensive/region/coogl/api':'/region/coogl/api',
    GRID_RANGE_API: IS_PROD?'/cd-comprehensive/grid-range':'/grid-range'
  }
};

// 是否使用直接地址（true: 使用直接地址, false: 使用代理地址）
const USE_DIRECT_URL = false;

// 获取当前使用的API基础URL
const getApiBaseUrl = (type) => {
  return USE_DIRECT_URL ? API_BASE_URLS.DIRECT[type] : API_BASE_URLS.PROXY[type];
};

// 调试日志函数
const logInfo = (...args) => {
  if (DEBUG) {
    console.log('==[CooGL]', ...args);
  }
};
const logError = (...args) => {
  if (DEBUG) {
    console.error('!!![CooGL]',...args);
  }
};

export class CooglLoadArea {
  params = {
    regionCode: '',
    gridType: '',
    startTime: '',
    endTime: '',
    dataCode: '',
    hasChildren: 1,
  }
  degreesArray = []
  levelOfMeter = {
    16: 20,
    14: 40,
    13: 75,
    12: 150,
    // 11: 400,
  }
  level
  opLevel
  graphic
  rightPickHandler
  compressCancelFn
  tinGraphic = []
  imageGraphicListOfCommunity = []
  imageGraphicList = []
  polygonGraphicList = []
  pickHandler = null

  //部件、事件、资源等拾取事件,返回拾取的详情
  imageGraphicOfCommunityEvent = null

  //设置在哪一级别加载当前区域的部件、事件、资源等数据  值为 6（区级） 9（街道） 12（社区、村）,默认为12
  loadPointsLevel = 12
  constructor(viewer, token) {
    this.viewer = viewer
    this.regionResult = regionResult.data
    this.token = token ?? CooGL.CooServer.defaultAccessToken
  }

  async mapInit() {
    logInfo('mapInit')
    if (this.pickHandler) {
      this.pickHandler()
      this.pickHandler = null
    }

    //清除画布
    this.clear()
    this.limitCamHeight()
    //默认加载一次市级的标注上图
    this.pickHandler = this.viewer.event.pick(e => {
      const { isCommunityImage, code: regionCode } =
        e?.primitive?.description || {}
      if (regionCode) {
        this.params.regionCode = regionCode
        //在这里判断 如果是社区、村的级别执行 setPoints
        //示例 判断条件根据实际情况而定
        //4 6 9 12
        const isSameLevel = regionCode?.length === this.loadPointsLevel
        if (isSameLevel) {
          this.setPoints(true)
        } else {
          this.addArea(true)
        }
      } else if (isCommunityImage && this.imageGraphicOfCommunityEvent) {
        this.imageGraphicOfCommunityEvent(e?.primitive?.description.detail)
      }
    })
    //增加右键功能,后退
    this.rightPickHandler = this.viewer.event.rightclick(e => {
      if (this.params.regionCode == 5101) return
      // 根据code查找父节点
      const parentCode = this.findParentCode(this.params.regionCode)
      this.params.regionCode = parentCode
      this.addArea(true)
    })
    await this.addArea(true)
    this.compressFn()
  }
  findParentCode(code) {
    if (!code) return null

    // 递归查找函数
    const findParent = (nodes, targetCode, parent = null) => {
      if (!nodes || !Array.isArray(nodes)) return null

      for (const node of nodes) {
        // 找到目标节点,返回父节点id
        if (node.id == targetCode) {
          return parent?.id || null
        }

        // 递归查找子节点
        if (node.children) {
          const found = findParent(node.children, targetCode, node)
          if (found !== null) return found
        }
      }
      return null
    }

    return findParent(this.regionResult, code)
  }
  /**
   * 添加区域
   * @param {string} regionCode - 区域编码
   * @param {string} gridtype - 网格类型
   *                           01：城市部件
   *                           02：事件
   *                           03：资源
   *                           04：单元网格
   *                           05：责任网格
   *                           06：任意网格
   *                           07：资源网格
   *                           08：感知设备
   * @param {string} startTime - 开始时间 格式：yyyy-MM-DD HH:mm:ss 可选
   * @param {string} endTime - 结束时间 格式：yyyy-MM-DD HH:mm:ss 可选
   */

  async addArea(clearData = false) {
    logInfo('addArea')
    const params = { ...this.params }
    if (clearData) {
      this.clear()
    } else {
      this.clearCurrentAreaData()
    }
    // const list = this.findRegionByCode(params.regionCode, true)
    const resList = await Promise.all([
      this.getRigionDetailByCode(params.regionCode),
      this.getAllRigionDetailByCode(params.regionCode),
    ])
    this.moveViewToPolygon(resList[0])
    const sons = resList[1].features
    for (const res of sons) {
      this.addPolygon(res)
    }

    const apiUrl = `${getApiBaseUrl('REGION_API')}/es/v1.0/bigdata_search_analysis`;
    fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        token: this.token,
      },
      body: JSON.stringify(params),
    })
      .then(res => res.json())
      .then(res => {
        const obj = res.data
        delete obj[params.regionCode]
        Object.entries(obj).map(([key, value]) => {
          const detailItem = sons.find(item => item.id === key)
          if (!detailItem) return
          const { _center, _name } = detailItem.properties
          const center = _center.split(',')
          const position = {
            x: +center[0],
            y: +center[1],
            z: 0,
          }
          const item = {
            num: value[0].num,
            code: key,
            position,
            name: _name,
          }
          this.addImage(item)
        })
      })
  }

  //获取指定regionCode的区域的经纬度以及中心点和下级区域的所有经纬度
  //FIXME: 这个接口需要自己实现
  async getRigionDetailByCode(regionCode) {
    if (!regionCode) return Promise.reject('regionCode is required')
    //参考已有代码
    // 获取geojson格式的区域边界数据
    // 获取txt格式的区域边界数据
    const apiUrl = `${getApiBaseUrl('GRID_RANGE_API')}/unit/${regionCode}`;
    const response = await fetch(apiUrl)
    return response.json()
  }
  async getAllRigionDetailByCode(regionCode) {
    if (!regionCode) return Promise.reject('regionCode is required')
    //参考已有代码
    // 获取geojson格式的区域边界数据
    // 获取txt格式的区域边界数据
    const apiUrl = `${getApiBaseUrl('GRID_RANGE_API')}/full/unit/${regionCode}`;
    const response = await fetch(apiUrl)
    return response.json()
  }

  addImage({ num, code, position, name }) {
    this.viewer
      .addLayer(
        CooGL.Layer.fromImageTextLabel({
          id: code,
          description: {
            code,
            name,
          },
          image:
            'data:image/png;base64, ',
          position,
          scale: 0.5,
          textContent: num,
          font: '16px simsum',
          pixelOffset: { x: 10, y: -100 },
          fillColor: '#fff',
          style: CooGL.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 4,
          outlineColor: '#000',
          distanceDisplayCondition: new CooGL.DistanceDisplayCondition(
            0,
            100000,
          ),
        }),
      )
      .then(res => {
        this.imageGraphicList.push(res)
      })
  }
  addCommunityImage(obj, position) {
    this.viewer
      .addLayer(
        CooGL.Layer.fromImageTextLabel({
          id: 'community' + '_' + obj.id,
          description: {
            isCommunityImage: true,
            detail: obj,
          },
          image:
            'data:image/png;base64,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',
          position,
          textContent: obj.name,
          font: '22px simsum',
          pixelOffset: { x: 0, y: -150 },
          fillColor: '#fff',
          style: CooGL.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 4,
          distanceDisplayCondition: new CooGL.DistanceDisplayCondition(
            0,
            10000,
          ),
          outlineColor: '#000',
        }),
      )
      .then(res => {
        this.imageGraphicListOfCommunity.push(res)
      })
  }
  addPolygon(polygonData) {
    const id = 'polygon' + '_' + polygonData.id
    this.viewer
      .addLayer(
        CooGL.Layer.fromGeoJsonGraphicResource({
          id,
          resource: {
            type: 'FeatureCollection',
            features: [polygonData],
          },
          customPolygonLabelOptions: function (positions, properties) {
            const center = properties._center.split(',')
            const textPosition = { x: center[0], y: center[1], z: 0 }
            return {
              positions,
              material: '#0B304B',
              textPosition,
              outline: true,
              outlineColor: '#36A6F5',
              outlineWidth: 2,
              fillColor: '#fff',
              font: '12px simsum',
              textContent: properties._name,
            }
          },
        }),
      )
      .then(res => {
        this.polygonGraphicList.push(res)
      })
  }

  //获取村、社区下的特定网格类型点位并上图
  async setPoints(clearData = false) {
    logInfo('setPoints')
    this.degreesArray = []
    if (clearData) {
      this.clear()
    }
    const res = await this.getRigionDetailByCode(this.params.regionCode)
    this.moveViewToPolygon(res)
    const coordinates = res.features[0].geometry.coordinates[0]
      .map(([x, y]) => `${x},${y}`)
      .join(';')
    // 构造请求参数
    const params = {
      regionCode: this.params.regionCode,
      dataCode: this.params.dataCode,
      gridtype: this.params.gridType,
      startTime: this.params.startTime,
      endTime: this.params.endTime,
      coordinates,
    }
    // 发送POST请求获取点位数据
    const apiUrl = `${getApiBaseUrl('REGION_API')}/es/v1.0/search`; 
    const response = await fetch(apiUrl, {
    // const response = await fetch('/region/coogl/api/es/v1.0/search', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        token: this.token,
      },
      body: JSON.stringify(params),
    })
    // 解析响应数据
    const res1 = await response.json()
    const { component, event, resource } = res1.data
    if(!component) return;
    if (component.length > 100) {
    }
    for (const v of component) {
      const position = { x: v.longitude, y: v.latitude, z: 0 }
      this.degreesArray.push(
        new CooGL.Vector3(position.x, position.y, position.z),
      )
      this.addCommunityImage(v, position)
    }
  }
  //计算多边形的包围盒，并将视角移动到包围盒的中心
  moveViewToPolygon(res) {
    const positions = res.features[0].geometry.coordinates.flat(Infinity)
    // 将扁平化的坐标数组重新组装成对象数组
    const positionObjects = []
    for (let i = 0; i < positions.length; i += 2) {
      positionObjects.push({
        x: positions[i],
        y: positions[i + 1],
        z: 0,
      })
    }
    // 添加多边形图层
    const bs = CooGL.BoundingSphere.fromPoints(
      CooGL.Vector3.degreesArray2cartesian(positionObjects),
    )
    // 定位到包围盒中心
    this.viewer.camera.flyToBoundingSphere(
      CooGL.Vector3.cartesian2degrees(bs.center), // 包围盒中心
      bs.radius, // 包围盒半径
      {
        duration: 1.5,
        offset: new CooGL.HeadingPitchRange(0, -Math.PI / 2, 0),
      },
    )
  }

  /**
   * 根据区域编码查找对应的区域信息及其子区域
   * @param {string} code - 区域编码(4/6/9/12位)
   * @returns {object|null} 返回找到的区域信息对象，未找到返回null
   */
  findRegionByCode(code, findSon = false) {
    if (!code) return null
    // 递归查找函数
    const findInTree = nodes => {
      if (!nodes || !Array.isArray(nodes)) return null

      for (const node of nodes) {
        // 匹配当前节点
        if (node.id == code) {
          if (findSon)
            return node.children.map(item => ({ ...item, children: null }))
          return node
        }

        // 递归查找子节点
        if (node.children) {
          const found = findInTree(node.children)
          if (found) return found
        }
      }
      return null
    }
    return findInTree(this.regionResult)
  }

  flyToArea([x, y], code) {
    const z = this.levelHeight[code.length]
    this.viewer.camera.flyTo({
      duration: 1.5,
      destination: {
        x,
        y,
        z,
      },
      orientation: {
        heading: 6.283185302776594,
        pitch: -1.5707963267948966,
        roll: 0,
      },
    })
  }
  compressFn() {
    this.compressCancelFn = this.viewer.renderEvent.addEventListener(() => {
      if (!this.degreesArray.length) return
      const curlevel =
        this.viewer.scene.globe._surface._debug.maxDepthVisited - 2
      if (this.level !== curlevel) {
        this.level = curlevel

        if (curlevel > 16) {
          if (this.opLevel < 17) {
            this.opLevel = curlevel
            for (const graphic of this.imageGraphicListOfCommunity) {
              graphic.show = true
            }
          }
          return
        }

        const diff = this.levelOfMeter[this.level]
        if (!diff) {
          return
        }
        this.opLevel = this.level
        const result = CooGL.PointsCompress.compute(this.degreesArray, diff)
        const values = Object.values(result)
        for (const graphic of this.imageGraphicListOfCommunity) {
          const position = graphic._graphic.imageTextLabel.position
          graphic.show = values.some(
            ({ x, y }) => position.x === x && position.y === y,
          )
        }
      }
    })
  }
  //清除标注
  clearCommunity() {
    for (const item of this.imageGraphicList) {
      this.viewer.removeLayer(item)
    }
    this.imageGraphicList = []
  }
  //清除画布
  clear() {
    for (const item of this.imageGraphicList) {
      this.viewer.removeLayer(item)
    }
    for (const item of this.polygonGraphicList) {
      this.viewer.removeLayer(item)
    }
    for (const item of this.imageGraphicListOfCommunity) {
      this.viewer.removeLayer(item)
    }
    this.imageGraphicListOfCommunity = []
    this.imageGraphicList = []
    this.polygonGraphicList = []
    this.degreesArray = []
  }

  clearCurrentAreaData() {
    const id = 'layer-' + this.params.regionCode
    const layer = this.viewer.getById(id)
    const index = this.imageGraphicList.indexOf(layer)
    if (layer) this.viewer.removeLayer(layer)
    if (index > -1) this.imageGraphicList.splice(index, 1)
  }

  limitCamHeight() {
    this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 300000
  }
  unlimitCamHeight() {
    this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = Infinity
  }
  destory() {
    this.compressCancelFn?.()
    this.rightPickHandler?.()

    this.clear()
    this.clearCommunity()
    this.pickHandler()
    this.pickHandler = null
    this.unlimitCamHeight()
  }
}
