const CMMAP_GL_VERSION = '1.0'

let loadPromise = null

function trimSlash(url) {
  return String(url || '').replace(/\/$/, '')
}

/** GIS 服务根地址，浏览器直连，如 http://117.180.211.5:8074 */
export function getGisBaseUrl() {
  return trimSlash(import.meta.env.VITE_GIS_BASE_URL)
}

export function getGisAssetUrls() {
  const base = getGisBaseUrl()
  const dist = `/agis/resources/v1/tile-server/dist/cmmap-gl/${CMMAP_GL_VERSION}`
  return {
    js: `${base}${dist}/cmmap-gl.js`,
    css: `${base}${dist}/cmmap-gl.css`
  }
}

export function getGisAccessToken() {
  return (import.meta.env.VITE_GIS_ACCESS_TOKEN || '').trim()
}

export function getGisMapStyle() {
  const style = (import.meta.env.VITE_GIS_MAP_STYLE || '').trim()
  return style || undefined
}

/** WMTS 图层名，如 baqing_wp */
export function getGisWmtsLayer() {
  return (import.meta.env.VITE_GIS_WMTS_LAYER || '').trim()
}

/** 高 zoom 时切换的 WMTS 图层，如 baqing_wp2 */
export function getGisWmtsLayer2() {
  return (import.meta.env.VITE_GIS_WMTS_LAYER2 || '').trim()
}

/** zoom 大于该值时叠加显示 VITE_GIS_WMTS_LAYER2（wp 始终保留在底层） */
export function getGisWmtsLayerSwitchZoom() {
  const z = Number(import.meta.env.VITE_GIS_WMTS_LAYER_SWITCH_ZOOM)
  return Number.isFinite(z) ? z : 16
}

export const GIS_WMTS_LAYER_IDS = {
  primary: 'gis-wmts-layer',
  secondary: 'gis-wmts-layer-2'
}

/** 瓦片边长（256 或 512）；512 时向 WMTS 追加 WIDTH/HEIGHT 请求高清瓦片 */
export function getGisTileSize() {
  const n = Number(import.meta.env.VITE_GIS_TILE_SIZE)
  return Number.isFinite(n) && n > 0 ? n : 256
}

function getGisWmtsTileMatrixSet() {
  return (import.meta.env.VITE_GIS_WMTS_TILEMATRIXSET || 'EPSG:3857_base').trim()
}

/** TileMatrix 模板，{z} 由地图替换，如 {z} 或 EPSG:3857_base:{z} */
function getGisWmtsTileMatrixTemplate() {
  return (import.meta.env.VITE_GIS_WMTS_TILE_MATRIX || '{z}').trim()
}

function getGisWmtsZoomOffset() {
  const n = Number(import.meta.env.VITE_GIS_WMTS_ZOOM_OFFSET)
  return Number.isFinite(n) ? n : 0
}

function buildWmtsTileUrlForLayer(layerName) {
  const base = getGisBaseUrl()
  const key = getGisAccessToken()
  const tileSize = getGisTileSize()
  const matrix = getGisWmtsTileMatrixTemplate()
  const matrixSet = encodeURIComponent(getGisWmtsTileMatrixSet())
  let url =
    `${base}/agis/maps/v1/wmts` +
    `?LAYER=${encodeURIComponent(layerName)}` +
    '&SERVICE=WMTS&REQUEST=GetTile' +
    `&TileMatrix=${matrix}` +
    '&TileCol={x}&TileRow={y}' +
    '&Version=1.0.0&FORMAT=image/png&style=' +
    `&tilematrixset=${matrixSet}` +
    `&key=${encodeURIComponent(key)}`
  if (tileSize !== 256) {
    url += `&WIDTH=${tileSize}&HEIGHT=${tileSize}`
  }
  return url
}

function buildWmtsRasterSource(layerName) {
  return {
    type: 'raster',
    tiles: [buildWmtsTileUrlForLayer(layerName)],
    tileSize: getGisTileSize(),
    scheme: 'xyz',
    minzoom: getGisMinZoom(),
    maxzoom: getGisTileMaxZoom()
  }
}

function buildWmtsRasterLayer(id, sourceId, visible = true) {
  return {
    id,
    type: 'raster',
    source: sourceId,
    layout: {
      visibility: visible ? 'visible' : 'none'
    },
    minzoom: getGisMinZoom(),
    maxzoom: 24,
    paint: {
      'raster-fade-duration': 300,
      'raster-resampling': 'linear'
    }
  }
}

/**
 * 瓦片请求改写：仅处理 zoom 偏移。
 * TileMatrix 上限由 style 里 source.maxzoom 控制，勿在此改写 col/row，否则易与引擎缓存键不一致导致 canceled。
 */
export function createGisTransformRequest() {
  const zoomOffset = getGisWmtsZoomOffset()
  if (!zoomOffset) {
    return undefined
  }
  return (url, resourceType) => {
    if (resourceType !== 'Tile' || !String(url).includes('/wmts')) {
      return { url }
    }
    const next = url.replace(
      /TileMatrix=(\d+)/,
      (_, z) => `TileMatrix=${parseInt(z, 10) + zoomOffset}`
    )
    return { url: next }
  }
}

/** 由 WMTS GetTile 模板生成 Mapbox Style（raster 源；可选双图层） */
export function buildWmtsMapStyle() {
  const base = getGisBaseUrl()
  const layer = getGisWmtsLayer()
  const layer2 = getGisWmtsLayer2()
  const key = getGisAccessToken()
  if (!base || !layer || !key) {
    return null
  }

  const sources = {
    'gis-wmts': buildWmtsRasterSource(layer)
  }
  const layers = [
    {
      id: 'gis-bg',
      type: 'background',
      paint: {
        'background-color': '#1a3a32'
      }
    },
    buildWmtsRasterLayer(GIS_WMTS_LAYER_IDS.primary, 'gis-wmts', true)
  ]

  if (layer2) {
    sources['gis-wmts-2'] = buildWmtsRasterSource(layer2)
    layers.push(buildWmtsRasterLayer(GIS_WMTS_LAYER_IDS.secondary, 'gis-wmts-2', false))
  }

  return {
    version: 8,
    sources,
    layers
  }
}

/** 根据 zoom 控制 wp2 叠加层显隐：wp 始终在底层，zoom > 16 时 wp2 叠在上方 */
export function syncWmtsLayerVisibility(map) {
  if (!map || typeof map.getZoom !== 'function') {
    return
  }
  const layer2 = getGisWmtsLayer2()
  if (!layer2 || typeof map.getLayer !== 'function') {
    return
  }
  if (!map.getLayer(GIS_WMTS_LAYER_IDS.secondary)) {
    return
  }

  const z = map.getZoom()
  const showOverlay = Number.isFinite(z) && z > getGisWmtsLayerSwitchZoom()

  if (typeof map.setLayoutProperty === 'function') {
    map.setLayoutProperty(
      GIS_WMTS_LAYER_IDS.secondary,
      'visibility',
      showOverlay ? 'visible' : 'none'
    )
  }
}

/** 优先使用 VITE_GIS_MAP_STYLE URL；否则按 WMTS 图层拼装样式对象 */
export function resolveGisMapStyle() {
  const explicit = getGisMapStyle()
  if (explicit) {
    return explicit
  }
  return buildWmtsMapStyle()
}

export function getGisDefaultCenter() {
  const raw = (import.meta.env.VITE_GIS_DEFAULT_CENTER || '94.05,31.92').trim()
  const parts = raw.split(',').map((n) => Number(n.trim()))
  if (parts.length >= 2 && parts.every((n) => Number.isFinite(n))) {
    return [parts[0], parts[1]]
  }
  return [94.05, 31.92]
}

export function getGisDefaultZoom() {
  const z = Number(import.meta.env.VITE_GIS_DEFAULT_ZOOM)
  return Number.isFinite(z) ? z : 17
}

export function getGisMinZoom() {
  const z = Number(import.meta.env.VITE_GIS_MIN_ZOOM)
  return Number.isFinite(z) ? z : 6
}

export function getGisMaxZoom() {
  const z = Number(import.meta.env.VITE_GIS_MAX_ZOOM)
  return Number.isFinite(z) ? z : 17
}

/** 瓦片源最高级别；默认比地图 maxZoom 低 1，最高级用低级瓦片放大，避免放到顶整屏发黑 */
export function getGisTileMaxZoom() {
  const explicit = Number(import.meta.env.VITE_GIS_TILE_MAX_ZOOM)
  if (Number.isFinite(explicit)) {
    return explicit
  }
  const max = getGisMaxZoom()
  const min = getGisMinZoom()
  return max > min ? max - 1 : max
}

export function isGisConfigured() {
  return !!(getGisBaseUrl() && getGisAccessToken() && resolveGisMapStyle())
}

/** 关闭 cmmap 遥测，避免 events.cmmap.com SSL 报错刷控制台 */
export function disableCmmapTelemetry(cmmapgl) {
  if (!cmmapgl) {
    return
  }
  try {
    if (typeof cmmapgl.setTelemetryEnabled === 'function') {
      cmmapgl.setTelemetryEnabled(false)
    }
  } catch {
    /* ignore */
  }
  try {
    if (cmmapgl.config) {
      cmmapgl.config.EVENTS_URL = ''
      if ('FEEDBACK_URL' in cmmapgl.config) {
        cmmapgl.config.FEEDBACK_URL = ''
      }
    }
  } catch {
    /* ignore */
  }
}

let telemetryBlocked = false

function blockCmmapTelemetryRequests() {
  if (telemetryBlocked || typeof window === 'undefined') {
    return
  }
  telemetryBlocked = true
  const shouldBlock = (url) => {
    const s = String(url || '')
    return s.includes('events.cmmap.com')
  }
  const nativeFetch = window.fetch
  if (typeof nativeFetch === 'function') {
    window.fetch = function blockedFetch(input, init) {
      const url = typeof input === 'string' ? input : input?.url
      if (shouldBlock(url)) {
        return Promise.resolve(new Response(null, { status: 204 }))
      }
      return nativeFetch.call(this, input, init)
    }
  }
  const XHR = window.XMLHttpRequest
  if (XHR && XHR.prototype) {
    const open = XHR.prototype.open
    XHR.prototype.open = function blockedOpen(method, url, ...rest) {
      this.__gisBlockedTelemetry = shouldBlock(url)
      return open.call(this, method, url, ...rest)
    }
    const send = XHR.prototype.send
    XHR.prototype.send = function blockedSend(...args) {
      if (this.__gisBlockedTelemetry) {
        return
      }
      return send.apply(this, args)
    }
  }
}

function loadCss(href) {
  return new Promise((resolve, reject) => {
    if (document.querySelector(`link[data-gis-sdk="cmmap-gl-css"]`)) {
      resolve()
      return
    }
    const link = document.createElement('link')
    link.rel = 'stylesheet'
    link.href = href
    link.dataset.gisSdk = 'cmmap-gl-css'
    link.onload = () => resolve()
    link.onerror = () => reject(new Error('GIS 样式加载失败'))
    document.head.appendChild(link)
  })
}

function loadScript(src) {
  return new Promise((resolve, reject) => {
    if (window.cmmapgl) {
      resolve(window.cmmapgl)
      return
    }
    const existing = document.querySelector(`script[data-gis-sdk="cmmap-gl-js"]`)
    if (existing) {
      existing.addEventListener('load', () => resolve(window.cmmapgl))
      existing.addEventListener('error', () => reject(new Error('GIS 脚本加载失败')))
      return
    }
    const script = document.createElement('script')
    script.src = src
    script.async = true
    script.dataset.gisSdk = 'cmmap-gl-js'
    script.onload = () => resolve(window.cmmapgl)
    script.onerror = () => reject(new Error('GIS 脚本加载失败'))
    document.head.appendChild(script)
  })
}

/** 动态加载 cmmap GL JS SDK，返回全局 cmmapgl */
export function loadGisSdk() {
  if (window.cmmapgl) {
    blockCmmapTelemetryRequests()
    disableCmmapTelemetry(window.cmmapgl)
    return Promise.resolve(window.cmmapgl)
  }
  if (!getGisBaseUrl()) {
    return Promise.reject(new Error('未配置 VITE_GIS_BASE_URL'))
  }
  if (!loadPromise) {
    const { js, css } = getGisAssetUrls()
    loadPromise = loadCss(css)
      .then(() => loadScript(js))
      .then((cmmapgl) => {
        if (!cmmapgl) {
          throw new Error('cmmapgl 未挂载到 window')
        }
        blockCmmapTelemetryRequests()
        disableCmmapTelemetry(cmmapgl)
        return cmmapgl
      })
      .catch((err) => {
        loadPromise = null
        throw err
      })
  }
  return loadPromise
}
