<template>
  <div>
    <a-row ::gutter="0">
      <a-col :span="12">
        <BasicTable @register="registerTable" @row-click="handRowClick">
          <template #toolbar>
            <a-button type="primary" @click="updateGeoTiff">更新最新影像</a-button>
            <a-button type="success" @click="updateYearWeekThumbnail">更新缩略图</a-button>
            <a-button type="error" @click="deleteGeoTiff">删除影像</a-button>
          </template>
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'layerName'">
              <span class="content-full">{{ record.layerName }}</span>
            </template>
            <template v-if="column.key === 'dataTable'">
              <span class="content-full">{{ record.dataTable }}</span>
            </template>
            <template v-if="column.key === 'shpPath'">
              <span class="content-full">{{ record.shpPath }}</span>
            </template>
            <template v-if="column.key === 'tiffPath'">
              <span class="content-full">{{ record.tiffPath }}</span>
            </template>
            <template v-if="column.key === 'createTime'">
              <span class="content-full">{{ record.createTime }}</span>
            </template>
            <template v-if="column.key === 'updateTime'">
              <span class="content-full">{{ record.updateTime }}</span>
            </template>
            <template v-if="column.key === 'accessUrl'">
              <a-image
                :src="'/geoserver/group/1/' + record.layerName + '/' + record.layerName + '.png'"
                :fallback="getUrl(record.accessUrl, record.layerName)"
                :style="{ marginRight: '10px' }"
                :width="100"
                :height="100"
                :preview="{
                  visible,
                  onVisibleChange: setVisible,
                }"
              />
            </template>
          </template>
        </BasicTable>
      </a-col>
      <a-col :span="12">
        <div>
          <MapComponent
            ref="mapboxComponentRef"
            style="
              position: absolute;
              top: 16px;
              left: 0px;
              height: calc(100vh - 112px);
              width: calc(85vh);
              z-index: 0;
            "
          />
        </div>
      </a-col>
    </a-row>

    <a-modal
      title="更新失败的影像"
      :open="failOpen"
      :maskClosable="false"
      :footer="null"
      :width="1000"
      @cancel="failOpenClose"
    >
      <FailYingxiang :failYingxiangData="failYingxiangData" />
    </a-modal>

    <a-modal
      title="选择更新的影像"
      style="top: 50px"
      :open="chooseUpdateOpen"
      :maskClosable="false"
      :width="600"
      :footer="null"
      @cancel="chooseUpdateClose"
    >
      <ChooseUpdate
        ref="chooseUpdateRef"
        :chooseUpdateData_yearweeks="chooseUpdateData_yearweeks"
        :chooseUpdateData_layernames="chooseUpdateData_layernames"
        @generateThumbnail="generateThumbnail"
      />
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, watch, onMounted, createVNode } from 'vue';
  // vben
  import { useMessage } from '@/hooks/web/useMessage';
  import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
  import { Modal } from 'ant-design-vue';
  import proj4 from 'proj4';
  import dayjs from 'dayjs';
  import { getAppEnvConfig } from '@/utils/env';
  import { BasicTable, useTable } from '@/components/Table';
  import { columns, searchFormSchema, data } from './util';
  import MapComponent from '@/views/demo/system/geoservermanagement/clound/mapComponent.vue';
  import FailYingxiang from './failYingxiang.vue';
  import ChooseUpdate from './chooseUpdate.vue';
  // api
  import {
    GeoTiffManagerUpdateGeoTiff,
    GeoTiffManagerLoadPage,
    GeoTiffManagerGet,
    GeoTiffManagerDeleteTifStore,
    GeoTiffManagerUpdateLayerGroupThumb,
  } from '@/api/demo/system';
  import { RecordList } from '../../geoservermanagement/page';

  // 图片路径拼接
  const { VITE_GLOB_API_URL } = getAppEnvConfig();
  const VITE_GLOB_API_URL_VAR = ref<String>(VITE_GLOB_API_URL + '/');

  const { createMessage } = useMessage();

  proj4.defs(
    'EPSG:4548',
    '+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs',
  );

  // 影像管理-----------------------------------------------------------------------------------------------
  const [registerTable, { reload, getSelectRows }] = useTable({
    title: '影像管理',
    api: GeoTiffManagerLoadPage,
    // dataSource: data,
    columns: columns,
    useSearchForm: true,
    formConfig: {
      labelWidth: 120,
      schemas: searchFormSchema,
    },
    showIndexColumn: true,
    rowSelection: {
      type: 'radio',
    },
    bordered: true,
    showTableSetting: true,
    handleSearchInfoFn(info) {
      return info;
    },
    immediate: false,
  });

  // 更新失败的影像-----------------------------------------------------------------------------------------
  const failOpen = ref(false);
  const failYingxiangData: any = ref();
  // 更新失败的影像弹窗关闭
  function failOpenClose() {
    failOpen.value = false;
  }

  // 更新tiff影像
  const updateGeoTiff = () => {
    GeoTiffManagerUpdateGeoTiff()
      .then((res) => {
        if (res.length == 0) {
          createMessage.success('影像更新成功');
          reload();
        } else {
          failYingxiangData.value = getFailYingxiangData(res);
          failOpen.value = true;
          reload();
        }
      })
      .catch((error) => {
        console.log(error);
      });
  };

  // 切割路径
  function getFailYingxiangData(table) {
    let result: any = [];
    table.forEach((fullPath) => {
      const lastSlashIndex = fullPath.lastIndexOf('/');
      if (lastSlashIndex != -1) {
        result.push({
          fileName: fullPath.substring(lastSlashIndex + 1),
          filePath: fullPath.substring(0, lastSlashIndex + 1),
        });
      }
    });
    return result;
  }

  // 删除tiff影像---------------------------------------------------------------------------------------
  const deleteGeoTiff = () => {
    let rows = getSelectRows();
    if (rows.length == 0) {
      return createMessage.warn('请勾选一条数据进行删除');
    }
    const record = rows[0];
    isPngImageUrl(getUrl(record.accessUrl, record.layerName))
      .then((isPng) => {
        if (isPng) {
          createMessage.warn('所选影像完好，不能删除！');
        } else {
          Modal.confirm({
            title: '是否确认删除此影像?',
            icon: createVNode(ExclamationCircleOutlined),
            onCancel() {},
            onOk() {
              // 删除有问题的影像
              let params = { stores: record.storeName };
              GeoTiffManagerDeleteTifStore(params).then((res) => {
                if (res) {
                  createMessage.success('所选影像删除成功！');
                  reload();
                } else {
                  createMessage.error('所选影像删除失败！');
                  reload();
                }
              });
            },
          });
        }
      })
      .catch(console.error);
  };

  // 判断链接获取到的图片是否是png
  async function isPngImageUrl(url) {
    try {
      const response = await fetch(url, { method: 'HEAD' });
      if (!response.ok) {
        throw new Error('请求失败');
      }
      const contentType = response.headers.get('content-type');
      return contentType && contentType.startsWith('image/png');
    } catch (error) {
      return false;
    }
  }

  // 在本地路径生成缩略图-------------------------------------------------------------------------------
  // 选择生成缩略图的影像ref、open、数据
  const chooseUpdateRef = ref();
  const chooseUpdateOpen = ref(false);
  const chooseUpdateData_yearweeks: any = ref([]);
  const chooseUpdateData_layernames: any = ref([]);
  // 选择更新的周数影像弹窗关闭
  function chooseUpdateClose() {
    chooseUpdateOpen.value = false;
    chooseUpdateRef.value.clearSelect_layernames();
    chooseUpdateRef.value.clearSelect_yearweeks();
  }
  // 在本地路径生成缩略图
  async function updateYearWeekThumbnail() {
    // allDataForClearMap = data;
    // 按照时间分类
    allDataForClearMap = allDataForClearMap.sort((a, b) => dayjs(b.dateDir) - dayjs(a.dateDir));
    let uniqueKeysArray = [...new Set(allDataForClearMap.map((item) => item.dateDir))];
    // 转换时间数组(年份-周数)
    uniqueKeysArray = [...new Set(uniqueKeysArray.map(convertToYearWeek))];
    // 生成对应年份-周数的缩略图
    chooseUpdateData_yearweeks.value = [];
    uniqueKeysArray.forEach((item, index) => {
      chooseUpdateData_yearweeks.value.push({
        rowname: item,
      });
    });
    // 影像名称更换全部影像的缩略图
    chooseUpdateData_layernames.value = [];
    allDataForClearMap.forEach((item, index) => {
      chooseUpdateData_layernames.value.push({
        rowname: item.layerName,
        bbox: getBboxFromUrl(item.accessUrl),
      });
    });
    chooseUpdateOpen.value = true;
  }

  // 生成缩略图
  async function generateThumbnail(
    layerNames,
    bbox,
    length,
    index,
    widthAndHeightValue = 1024,
    numValue = 1,
  ) {
    if (bbox) {
      // 检查bbox是否是ESG:4326，不是的话转换成
      let bboxSplit = bbox.split(',');
      const result1 = isProjectedCoordinates(parseFloat(bboxSplit[0]), parseFloat(bboxSplit[1]));
      if (result1) {
        const result2 = isProjectedCoordinates(parseFloat(bboxSplit[2]), parseFloat(bboxSplit[3]));
        bbox = result1.concat(result2).toString();
      }
      GeoTiffManagerUpdateLayerGroupThumb({
        layerGroups: layerNames,
        bbox: bbox,
        num: 1,
        width: widthAndHeightValue,
        height: widthAndHeightValue,
      })
        .then((res) => {
          if (res && length == index) {
            createMessage.success('生成新的缩略图成功！');
            chooseUpdateRef.value.clearSelect_layernames();
            chooseUpdateRef.value.loading_layernames = false;
          } else if (length == index) {
            createMessage.error('生成新的缩略图失败！');
            chooseUpdateRef.value.loading_layernames = false;
          }
        })
        .catch((error) => {
          if (length == index) {
            createMessage.error('生成新的缩略图失败！');
            chooseUpdateRef.value.loading_layernames = false;
          }
        });
    } else {
      // 分割的生成缩略图
      GeoTiffManagerUpdateLayerGroupThumb({
        layerGroups: layerNames,
        num: numValue,
        width: widthAndHeightValue,
        height: widthAndHeightValue,
      })
        .then((res) => {
          if (res) {
            createMessage.success('生成新的缩略图成功！');
            chooseUpdateRef.value.loading_yearweeks = false;
            chooseUpdateRef.value.clearSelect_yearweeks();
            if (numValue != 1) {
              // 生成总的缩略图
              GeoTiffManagerUpdateLayerGroupThumb({
                layerGroups: layerNames,
                num: 1,
                width: widthAndHeightValue,
                height: widthAndHeightValue,
              });
            }
          } else {
            createMessage.error('生成新的缩略图失败！');
            chooseUpdateRef.value.loading_yearweeks = false;
          }
        })
        .catch((error) => {
          createMessage.error('生成新的缩略图失败！');
          chooseUpdateRef.value.loading_yearweeks = false;
        });
    }
  }

  // 获取年份-周数
  function convertToYearWeek(dateStr) {
    const date = dayjs(dateStr, 'YYYYMMDD');
    // 返回格式化的字符串
    return `${date.year()}-${getWeekOfYear(date)}`;
  }

  // 每周从周一开始
  function getWeekOfYear(date) {
    const firstDayOfYear = dayjs(date).startOf('year');
    const firstMondayOfYear =
      firstDayOfYear.day() === 1
        ? firstDayOfYear
        : firstDayOfYear.add(1 - firstDayOfYear.day(), 'day');
    const diffInDays = date.diff(firstMondayOfYear, 'days');
    const weekNumber = Math.floor(diffInDays / 7) + 1;
    return weekNumber;
  }

  // 行选中-----------------------------------------------------------------------------------------
  const mapboxComponentRef = ref();
  function handRowClick(record) {
    allDataForClearMap.forEach((data) => {
      mapboxComponentRef.value.clearTaskLayer(data.layerName);
    });
    let lngLat = getlngLatByAccessUrl(record.accessUrl);
    let chooseRows: any = [];
    record.bbox = getBboxFromUrl(record.accessUrl);
    chooseRows.push(record);
    mapboxComponentRef.value.GeoTiffManagerRaster(chooseRows, lngLat, 11, true);
  }

  // 获取中心点的坐标
  function getlngLatByAccessUrl(accessUrl) {
    let bbox = getBboxFromUrl(accessUrl);
    let lngLat = getCenterPoint(bbox);
    // 检测坐标系
    const result = isProjectedCoordinates(parseFloat(lngLat[0]), parseFloat(lngLat[1]));
    if (result) {
      lngLat[0] = result[0];
      lngLat[1] = result[1];
    }
    return lngLat;
  }

  function isProjectedCoordinates(x, y) {
    // 检查是否在地理坐标系的范围内
    const isGeoXInRange = -180 <= x && x <= 180;
    const isGeoYInRange = -90 <= y && y <= 90;
    // 定义坐标系
    const fromCrs1 = 'EPSG:3857'; // 假设输入坐标是 Web Mercator
    const fromCrs2 = 'EPSG:4548';
    const toCrs = 'EPSG:4326'; // 目标坐标系是地理坐标系
    // 如果不在地理坐标系范围内，则认为是投影坐标系
    if (!isGeoXInRange || !isGeoYInRange) {
      // 转换坐标
      // 根据输入坐标的范围来判断是哪个坐标系
      const fromCrs = isProjectedCoordinate(x, y) ? fromCrs2 : fromCrs1;
      return proj4(fromCrs, toCrs, [x, y]);
    } else {
      return false;
    }
  }

  const isProjectedCoordinate = (x, y) => {
    // 检查坐标是否符合 EPSG:4548 的大致范围
    const is4548XInRange = 0 <= x && x <= 1000000;
    const is4548YInRange = 0 <= y && y <= 6000000;
    return is4548XInRange && is4548YInRange;
  };

  // 从参数中获取 bbox 的值
  function getBboxFromUrl(url) {
    const urlObj = new URL(url);
    const params = new URLSearchParams(urlObj.search);
    const bbox = params.get('bbox');
    return bbox;
  }

  // 计算中心点
  function getCenterPoint(bbox) {
    const coords = bbox.split(',').map((coord) => parseFloat(coord));
    const [minLon, minLat, maxLon, maxLat] = coords;
    const centerLon = (minLon + maxLon) / 2;
    const centerLat = (minLat + maxLat) / 2;
    return [centerLon, centerLat];
  }

  // 缩略图的预览不使用----------------------------------------------------------------------------
  const visible = ref<boolean>(false);
  const setVisible = (value): void => {
    visible.value = false;
  };

  // 从geoserver获取缩略图
  function getUrl(accessUrl, name) {
    let r1 = [117.34046403513817, 34.331716698906675];
    let r2 = [119.27763051149853, 36.263686454243626];
    let size = 4096;
    if (accessUrl) {
      let bbox: any = getBboxFromUrl(accessUrl);
      // 检查bbox是否是ESG:4326，不是的话转换成
      let bboxSplit = bbox.split(',');
      const result1 = isProjectedCoordinates(parseFloat(bboxSplit[0]), parseFloat(bboxSplit[1]));
      if (result1) {
        const result2 = isProjectedCoordinates(parseFloat(bboxSplit[2]), parseFloat(bboxSplit[3]));
        bbox = result1.concat(result2).toString();
      }
      const coords = bbox.split(',').map((coord) => parseFloat(coord));
      r1 = [coords[0], coords[1]];
      r2 = [coords[2], coords[3]];
      size = 256;
    }
    let titeUrl: any = null;
    if (new URL(VITE_GLOB_API_URL).hostname == 'localhost') {
      titeUrl =
        'http://localhost:8080/geoserver/my_workspace/wms?service=WMS&version=1.1.0&request=GetMap&layers=my_workspace:';
    } else {
      titeUrl =
        'http://192.168.10.141:8080/geoserver/my_workspace/wms?service=WMS&version=1.1.0&request=GetMap&layers=my_workspace:';
    }
    let url =
      titeUrl +
      name +
      '&styles=&bbox=' +
      r1[0] +
      ',' +
      r1[1] +
      ',' +
      r2[0] +
      ',' +
      r2[1] +
      '&width=' +
      size +
      '&height=' +
      size +
      '&srs=EPSG:4326&format=image/png&TRANSPARENT=TRUE';
    return url;
  }

  // 用于去除分页后地图还有前一页的图层--------------------------------------------------------------
  let allDataForClearMap: any = [];
  function forClearMap() {
    GeoTiffManagerLoadPage({
      page: 1,
      limit: 100000,
    }).then((res) => {
      allDataForClearMap = res.items;
    });
  }

  onMounted(() => {
    reload();
    // 用于去除分页后地图还有前一页的图层
    forClearMap();
  });
</script>
<style lang="less" scoped>
  .content-full {
    white-space: pre-wrap;
    word-break: break-all;
    overflow-wrap: break-word;
    max-width: 100%;
    display: block;
  }
  ::v-deep .ant-image-mask {
    display: none !important;
  }
</style>
