<template>
  <div class="show-map-div">
    <div class="select-menu">
      <div class="add-on-map">
        <a-checkbox v-model:checked="addOnMap" @change="(e) => addOnMapChange(e.target.checked)">
          叠加到地图
        </a-checkbox>
      </div>
      <a-radio-group v-model:value="selectType" button-style="solid" size="small">
        <a-radio-button :value="0">专题图</a-radio-button>
        <!-- <a-radio-button :value="1">截图</a-radio-button> -->
        <!-- <a-radio-button :value="2">天地图</a-radio-button> -->
      </a-radio-group>
    </div>
    <div class="slider-menu">
      <!-- <a-slider
        v-if="addOnMap && sliderShow"
        v-model:value="nowSliderValue"
        vertical="true"
        :tooltipOpen="false"
        :tip-formatter="getValue"
        :marks="marks"
        :step="1"
        min="0"
        max="10"
        @afterChange="sliderChange"
      >
        <template #mark="{ label, point }">
          <template v-if="point >= 0">
            <span
              :style="{
                color: 'white',
                position: 'relative',
                top: `${7}px`,
                left: `${3}px`,
              }"
              >{{ label }}</span
            >
          </template>
        </template>
      </a-slider>
      <a-tooltip placement="right">
        <template #title>
          <span>设置叠加到地图的图片的透明度</span>
        </template>
        <PlusCircleOutlined
          v-if="(addOnMap || selectType == 2)  && sliderShow"
          :style="{
            position: 'absolute',
            fontSize: '18px',
            bottom: '-28px',
            right: '8px',
            color: 'white',
          }"
          @click="changeSliderShow"
        />
        <MinusCircleOutlined
          v-if="(addOnMap || selectType == 2)  && !sliderShow"
          :style="{
            position: 'absolute',
            fontSize: '18px',
            bottom: '-28px',
            right: '8px',
            color: 'white',
          }"
          @click="changeSliderShow"
        />
      </a-tooltip> -->
    </div>
    <div class="expandShow-menu">
      <FullscreenOutlined
        v-if="addOnMap && !expandShow"
        :style="{
          position: 'absolute',
          fontSize: '28px',
          bottom: '-65px',
          right: '4px',
          color: 'white',
          zIndex: 11,
        }"
        @click="expand(!expandShow)"
      />
      <FullscreenExitOutlined
        v-if="addOnMap && expandShow"
        :style="{
          position: 'fixed',
          fontSize: '35px',
          bottom: '20px',
          right: '20px',
          color: 'white',
          zIndex: 1012,
        }"
        @click="expand(!expandShow)"
      />
    </div>
    <template v-if="selectType === 0">
      <a-image
        v-if="!addOnMap"
        :width="470"
        :height="470"
        :src="convertValidUrl(showData.url)"
        :preview="{
          src: showData.previewUrl,
        }"
      />
    </template>
    <template v-if="selectType === 1 && !addOnMap">
      <a-image
        v-if="!addOnMap"
        :width="470"
        :height="470"
        :src="convertValidUrl(showData.urlxian)"
        :preview="{
          src: showData.previewUrlXian,
        }"
      />
    </template>
    <ModalMap
      v-if="addOnMap"
      :width="modalMapWidth"
      :height="modalMapHeight"
      :zIndex="modalMapZIndex"
      :position="modalMapPosition"
      :centerAndZoom="props.data"
      @getMap="getMap"
    />
  </div>
  <a-tabs v-model:activeKey="activeKey">
    <a-tab-pane key="1" tab="土地分类">
      <ShowTableList
        :columns="landClassificationColumns"
        :data="landClassifyTable"
        :title="'土地利用现状查询结果'"
      />
    </a-tab-pane>
    <a-tab-pane key="2" tab="耕地占用">
      <ShowTableList
        :columns="landPlanningColumns"
        :data="plowLandOccupyTable"
        :title="'土地规划查询结果'"
      />
    </a-tab-pane>
  </a-tabs>
</template>

<script setup lang="ts">
  import { ref, defineProps, computed, watch, onMounted } from 'vue';
  import {
    PlusCircleOutlined,
    MinusCircleOutlined,
    FullscreenOutlined,
    FullscreenExitOutlined,
  } from '@ant-design/icons-vue';
  import ShowTableList from '@/views/dashboard/test/components/ShowTableList/index.vue';
  import ModalMap from './ModalMap/index.vue';
  // 图片路径拼接
  import { getAppEnvConfig } from '@/utils/env';
  const { VITE_GLOB_API_URL } = getAppEnvConfig();
  const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL + '/');

  const props = defineProps(['data']);

  let map;
  // 土地分类和耕地占用
  const activeKey = ref('1');
  // 是否叠加到地图
  const addOnMap = ref(true);
  // 专题图、截图、天地图
  const selectType = ref(0);

  watch(
    // 土地分类和耕地占用
    () => activeKey.value,
    () => {
      // 查看结果进入就显示叠加的图
      if (addOnMap.value) {
        addOnMapChange(true);
      }
    },
  );

  watch(
    // 专题图、截图、天地图
    () => selectType.value,
    () => {
      // 查看结果进入就显示叠加的图
      if (addOnMap.value) {
        addOnMapChange(true);
      }
    },
  );

  // 表格数据
  const landClassifyTable = computed(() => {
    let data;
    props.data?.forEach((item, index) => {
      if (item.name == '土地分类') {
        data = { ...item };
      }
      // 第一次打开
      if (index == 0) {
        // 移动位置
        let fourpoint = JSON.parse(`[${item.fourpoint}]`);
        setTimeout(() => {
          moveLocation(fourpoint);
        }, 200);
        // 查看结果进入就显示叠加的图
        addOnMapChange(true);
      }
      // 生成白色底色的预览图片
      if (item.url && !item.previewUrl) {
        changeTransparentColorToWhite(convertValidUrl(item.url)).then((resultImageUrl) => {
          item.previewUrl = resultImageUrl;
        });
      }
      if (item.urlxian && !item.previewUrlXian) {
        changeTransparentColorToWhite(convertValidUrl(item.urlxian)).then((resultImageUrl) => {
          item.previewUrlXian = resultImageUrl;
        });
      }
    });
    return data && data.list;
  });

  const plowLandOccupyTable = computed(() => {
    let data;
    props.data?.forEach((item) => {
      if (item.name == '耕地占用') {
        data = { ...item };
      }
    });
    return data && data.list;
  });

  const showData = computed(() => {
    let data;
    switch (activeKey.value) {
      case '1':
        props.data?.forEach((item) => {
          if (item.name == '土地分类') {
            data = { ...item };
          }
        });
        return data;
      case '2':
        props.data?.forEach((item) => {
          if (item.name == '耕地占用') {
            data = { ...item };
          }
        });
        return data;
    }
  });
  // 表格结构
  const landClassificationColumns = [
    {
      title: '地类名称',
      dataIndex: 'type',
      key: 'type',
      width: 180,
      sorter: (a, b) => a.landName - b.landName,
      sortDirections: ['descend', 'ascend'],
    },
    {
      title: '联合属性',
      dataIndex: 'stats',
      key: 'stats',
      width: 100,
      sorter: (a, b) => a.stats.length - b.stats.length,
      sortDirections: ['descend', 'ascend'],
    },
    {
      title: '面积（亩）',
      dataIndex: 'area',
      key: 'area',
      width: 150,
      sorter: (a, b) => a.area - b.area,
      sortDirections: ['descend', 'ascend'],
    },
  ];
  const landPlanningColumns = [
    {
      title: '类型',
      dataIndex: 'type',
      key: 'type',
      sorter: (a, b) => a.type.length - b.type.length,
      sortDirections: ['descend', 'ascend'],
    },
    {
      title: '面积（亩）',
      dataIndex: 'area',
      key: 'area',
      sorter: (a, b) => a.area - b.area,
      sortDirections: ['descend', 'ascend'],
    },
  ];
  const getMap = (value) => {
    map = value;
  };

  // 定义预加载图片的方法------------------------------------------------------------------------------------------------
  const addOnMapChange = (value) => {
    setTimeout(async () => {
      let url: any = '';
      let fourpoint = '';
      if (value) {
        let data: any = {};
        if (activeKey.value == '1') {
          props.data.forEach((item) => {
            if (item.name == '土地分类') {
              data = { ...item };
            }
          });
        } else if (activeKey.value == '2') {
          props.data.forEach((item) => {
            if (item.name == '耕地占用') {
              data = { ...item };
            }
          });
        }
        if (selectType.value == 0 || selectType.value == 2) {
          url = convertValidUrl(data.url);
          fourpoint = JSON.parse(`[${data.fourpoint}]`);
        }
        if (selectType.value == 1) {
          url = convertValidUrl(data.urlxian);
          fourpoint = JSON.parse(`[${data.fourpoint}]`);
        }
        // 图片预加载
        let image = new Image();
        image.crossOrigin = 'anonymous';
        image.src = url;
        image.onload = () => {
          // 创建Canvas元素
          const canvas = document.createElement('canvas');
          canvas.width = image.width;
          canvas.height = image.height;
          // 获取Canvas绘图上下文
          const ctx = canvas.getContext('2d');
          // 在Canvas上绘制图片
          ctx.drawImage(image, 0, 0, image.width, image.height);
          // 将Canvas内容转换为图片的数据URL
          const dataURL = canvas.toDataURL('image/png');
          // 移除旧的图层和源
          if (map) {
            if (map.getLayer('radar-layer')) {
              map.removeLayer('radar-layer');
            }
            if (map.getSource('radar')) {
              map.removeSource('radar');
            }
          }
          // 添加新的源和图层
          map.addSource('radar', {
            type: 'image',
            url: dataURL,
            coordinates: fourpoint,
          });
          map.addLayer({
            id: 'radar-layer',
            type: 'raster',
            source: 'radar',
            paint: {
              'raster-opacity': parseFloat(getValue(nowSliderValue.value)),
            },
          });
          moveLocation(fourpoint);
        };
      }
      sliderShow.value = false;
      // console.log(337, props.data);
    }, 500);
  };

  // 移动位置
  function moveLocation(fourpoint) {
    let x = 0;
    let y = 0;
    let length = fourpoint.length;
    for (let i = 0; i < fourpoint.length; i++) {
      x = x + fourpoint[i][0];
      y = y + fourpoint[i][1];
    }
    x = x / length;
    y = y / length;
    if (map) {
      map.jumpTo({
        center: [x, y],
        zoom: calculateZoom(fourpoint),
      });
    }
    return [x, y];
  }

  // 计算合适的缩放级别
  function calculateZoom(points) {
    // 计算边界框
    const nw = points[0];
    const ne = points[1];
    const se = points[2];
    const latRange = Math.abs(nw[1] - se[1]);
    const lngRange = Math.abs(nw[0] - ne[0]);
    // 计算缩放级别
    const zoomLat = Math.log2(360 / latRange) - 1;
    const zoomLng = Math.log2(360 / lngRange) - 1;
    // 返回最小的缩放级别，并保留小数后两位
    return Math.min(zoomLat * 1.05, zoomLng * 1.05).toFixed(2);
  }

  // 全屏--------------------------------------------------------------------------------------------------------------
  const modalMapWidth = ref('470px');
  const modalMapHeight = ref('470px');
  const modalMapZIndex = ref(10);
  const modalMapPosition = ref('absolute');
  const expandShow = ref(false);
  // 全屏
  function expand(value) {
    if (value) {
      modalMapWidth.value = '100%';
      modalMapHeight.value = '100%';
      modalMapZIndex.value = 1011;
      modalMapPosition.value = 'fixed';
    } else {
      modalMapWidth.value = '470px';
      modalMapHeight.value = '470px';
      modalMapZIndex.value = 10;
      modalMapPosition.value = 'absolute';
    }
    setTimeout(() => {
      map.resize();
    }, 100);
    expandShow.value = value;
  }

  // 图片------------------------------------------------------------------------------------------------------------
  // 正则表达式验证URL，转换
  function convertValidUrl(url: string): boolean {
    const regex =
      /^(?:http|ftp)s?:\/\/(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[?[A-F0-9]*:[A-F0-9:]+\]?)(?::\d+)?(?:\/?|[\/?]\S+)$/i;
    let result: any = regex.test(url) ? url : VITE_GLOB_API_URL_VAR.value + url;
    return result;
  }
  // 预览变成白色的底色
  async function changeTransparentColorToWhite(imageUrl) {
    return new Promise((resolve, reject) => {
      // 创建一个新的 Image 对象
      const img = new Image();
      img.crossOrigin = 'Anonymous'; // 处理跨域问题
      img.src = imageUrl;
      img.onload = () => {
        // 创建一个 canvas 元素
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        // 设置 canvas 的尺寸与图片相同
        canvas.width = img.width;
        canvas.height = img.height;
        // 将图片绘制到 canvas 上
        ctx.drawImage(img, 0, 0);
        // 获取 canvas 的图像数据
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        const data = imageData.data;
        // 遍历每个像素，将透明部分变成白色
        for (let i = 0; i < data.length; i += 4) {
          if (data[i + 3] === 0) {
            // 如果 alpha 通道为 0（完全透明）
            data[i] = 255; // 红色通道
            data[i + 1] = 255; // 绿色通道
            data[i + 2] = 255; // 蓝色通道
            data[i + 3] = 255; // alpha 通道（不透明）
          }
        }
        // 将修改后的图像数据放回 canvas
        ctx.putImageData(imageData, 0, 0);
        // 将 canvas 内容转换为图片数据 URL
        const resultImageUrl = canvas.toDataURL('image/png');
        // 返回处理后的新图片的 URL
        resolve(resultImageUrl);
      };
      img.onerror = (error) => {
        reject(error);
      };
    });
  }

  // 透明度-----------------------------------------------------------------------------------------------------------
  const nowSliderValue = ref<number>(10);
  // 标识
  const marks = ref<Record<number, any>>({
    0: 0,
    1: 0.1,
    2: 0.2,
    3: 0.3,
    4: 0.4,
    5: 0.5,
    6: 0.6,
    7: 0.7,
    8: 0.8,
    9: 0.9,
    10: 1,
  });
  // 获取标识值
  const getValue = (key: number) => {
    if (marks.value) {
      return marks.value[key];
    }
  };
  // 发生改变
  const sliderChange = (key: number) => {
    map.setPaintProperty('radar-layer', 'raster-opacity', parseFloat(getValue(key)));
  };
  // 设置叠加到地图的图片的透明度
  const sliderShow = ref(false);
  function changeSliderShow() {
    sliderShow.value = !sliderShow.value;
  }
</script>

<style lang="scss" scoped>
  .select-menu {
    display: flex;
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 100;
    .add-on-map {
      width: 110px;
      background: rgba(0, 0, 0, 0.2);
      display: flex;
      align-items: center;
      justify-content: center;
      border-top-left-radius: 5px;
      border-bottom-left-radius: 5px;
    }
  }
  .slider-menu {
    position: absolute;
    right: 10px;
    top: 90px;
    height: 300px;
    z-index: 100;
  }
  .show-map-div {
    width: 470px;
    height: 470px;
    position: relative;
  }
  .expandShow-menu {
    position: absolute;
    right: 10px;
    bottom: 80px;
  }
</style>
