import { Tile } from "ol/layer";
import TileWMTS from "ol/tilegrid/WMTS";
import { WMTS } from "ol/source";
import { Projection, get as getProjection, getTransform } from "ol/proj";
import { register } from "ol/proj/proj4";
import proj4 from "proj4";
import { applyTransform, getTopLeft, getWidth } from "ol/extent";

// 注册cgcs2000坐标转换器
proj4.defs(
  "EPSG:4490",
  'GEOGCS["China Geodetic Coordinate System 2000",DATUM["China_2000",SPHEROID["CGCS2000",6378137,298.257222101,AUTHORITY["EPSG","1024"]],AUTHORITY["EPSG","1043"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4490"]]'
);
register(proj4);

const getTileWMTSTileGrid = (from: Projection, to: Projection) => {
  const projectionExtent = to.getExtent();
  const origin = projectionExtent ? getTopLeft(projectionExtent) : [-180, 90];
  const fromLonLat = getTransform(from, to);
  const width = projectionExtent
    ? getWidth(projectionExtent)
    : getWidth(applyTransform([-180.0, -90.0, 180.0, 90.0], fromLonLat));

  const resolutions = [];
  const matrixIds = [];
  for (let z = 1; z < 19; z++) {
    resolutions[z] = width / (256 * Math.pow(2, z));
    matrixIds[z] = z.toString();
  }

  return new TileWMTS({
    origin: origin,
    resolutions: resolutions,
    matrixIds: matrixIds,
  });
};

const tileTMaps = {
  全球境界: "ibo",
  地形注记: "cta",
  地形晕渲: "ter",
  影像注记: "cia",
  影像底图: "img",
  矢量注记: "cva",
  矢量底图: "vec",
};

const wmtsProjection = getProjection("EPSG:4490")!;
const tileGridCache: { [key in string]: TileWMTS } = {};
const typeWMTSCacne: { [key in string]: WMTS } = {};

const getWMTS = (type: TileType, mapEpsg: string) => {
  if (typeWMTSCacne[mapEpsg + type]) {
    return typeWMTSCacne[mapEpsg + type];
  }
  const wmtsTileGrid =
    mapEpsg in tileGridCache
      ? tileGridCache[mapEpsg]
      : getTileWMTSTileGrid(getProjection(mapEpsg)!, wmtsProjection);

  const layer = tileTMaps[type];
  const key = "69167db5c31974a619fe60f0c4cd21b5";
  const url = `https://t0.tianditu.gov.cn/${layer}_c/wmts?tk=${key}`;
  return new WMTS({
    url,
    crossOrigin: "anonymous", // 设置跨域
    layer,
    version: "1.0.0",
    matrixSet: "c",
    format: "tiles",
    projection: wmtsProjection,
    requestEncoding: "KVP",
    style: "default",
    tileGrid: wmtsTileGrid,
  });
};

export type TileType = keyof typeof tileTMaps;

export const baseTileLayer = new Tile();
export const geoTileLayer = new Tile({
  source: getWMTS("矢量注记", "EPSG:4326"),
});
export const setBaseTileType = (type: TileType) => {
  baseTileLayer.setSource(getWMTS(type, "EPSG:4326"));
};
