<template>
  <div>
    <a-row ::gutter="0">
      <a-col :span="5">
        <div class="RightBox">
          <a-tooltip class="box-item" placement="top">
            <template #title>
              <span>上一年</span>
            </template>
            <a-button type="text" @click="handleSubYear">
              <Icon icon="bi:chevron-double-left" style="color: #ffffff" :size="30" />
            </a-button>
          </a-tooltip>
          <a-tooltip class="box-item" placement="top">
            <template #title>
              <span>上一月</span>
            </template>
            <a-button type="text" style="margin-left: 10px" @click="handleSubMouth">
              <Icon icon="bi:chevron-left" style="color: #ffffff" :size="30" />
            </a-button>
          </a-tooltip>

          <a-tooltip class="box-item" placement="top">
            <template #title>
              <span>播放/暂停</span>
            </template>
            <a-button type="text" style="margin-left: 10px" @click="handlePlay">
              <Icon v-if="!playSwitch" icon="bi:play-circle" style="color: #ffffff" :size="30" />
              <Icon v-if="playSwitch" icon="bi:pause-circle" style="color: #ffffff" :size="30" />
            </a-button>
          </a-tooltip>

          <a-tooltip class="box-item" placement="top">
            <template #title>
              <span>下一月</span>
            </template>
            <a-button type="text" style="margin-left: 10px" @click="handleAddMouth">
              <Icon icon="bi:chevron-right" style="color: #ffffff" :size="30" />
            </a-button>
          </a-tooltip>
          <a-tooltip class="box-item" placement="top">
            <template #title>
              <span>下一年</span>
            </template>
            <a-button type="text" style="margin-left: 10px" @click="handleAddYear">
              <Icon icon="bi:chevron-double-right" style="color: #ffffff" :size="30" />
            </a-button>
          </a-tooltip>
        </div>
      </a-col>
      <a-col :span="18" @wheel.stop="handleScroll">
        <div class="timeBox">
          <a-slider
            v-model:value="nowValue"
            :tooltipOpen="false"
            :tip-formatter="getValue"
            :marks="marks"
            :step="1"
            :min="minCount"
            :max="maxCount"
            @afterChange="sliderChange"
          >
            <template #mark="{ label, point }">
              <template v-if="bottomPoint.includes(point)">
                <span
                  :style="{
                    color: 'white',
                    position: 'relative',
                    right: `${30}px`,
                  }"
                >
                  {{ label.slice(0, 6) }}
                </span>
              </template>
              <template v-if="topPoint.includes(point)">
                <span
                  :style="{
                    position: 'relative',
                    bottom: `${10 + 35 + 0 * countLines(label, point)}px`,
                  }"
                >
                  <a-popover>
                    <template #content>
                      <div v-html="getNameByJxnanme(label)" />
                    </template>
                    <!-- <a-tag closable color="#2db7f5">{{ label }}</a-tag> -->
                    <img src="/display/position.png" />
                  </a-popover>
                </span>
              </template>
            </template>
          </a-slider>
        </div>
      </a-col>
      <a-col :span="1">
        <a-tooltip placement="top">
          <template #title>
            <span>重置时间轴</span>
          </template>
          <ReloadOutlined
            :spin="resetSpin"
            :style="{
              color: 'white',
              fontSize: '20px',
              position: 'absolute',
              marginTop: '10px',
              right: '60px',
            }"
            @click="resetTimeLine"
          />
        </a-tooltip>
        <a-tooltip placement="top">
          <template #title>
            <span>时间轴的选项只影响历史影像</span>
          </template>
          <QuestionCircleOutlined
            :style="{ color: 'white', fontSize: '20px', position: 'absolute', marginTop: '10px' }"
          />
        </a-tooltip>
      </a-col>
    </a-row>
  </div>
</template>

<script lang="ts" setup>
  // vue
  import { ref, watch, computed, onBeforeMount, onMounted, onBeforeUpdate, onUpdated } from 'vue';
  import Icon from '@/components/Icon/Icon.vue';
  import { QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons-vue';
  import dayjs from 'dayjs';
  import { GeoTiffManagerLoadPage } from '@/api/demo/system';
  import { cloneDeep } from 'lodash-es';

  const emit = defineEmits(['handleNowValueChange']);

  const nowValue = ref<number>(0);
  const minCount = ref(1);
  const maxCount = ref(parseInt(dayjs().endOf('year').dayOfYear()));
  const marks: any = ref<Record<number, any>>();
  const allDays: any = ref<Record<number, any>>();
  let allData: any = {};
  const sliderValue: any = ref({});
  const topPoint = ref([]);
  const bottomPoint = ref([]);
  let yignxiangNames: any = [];

  const currentZIndex = ref(1);

  watch(
    () => allDays.value,
    () => {
      marks.value = {};
      topPoint.value = [];
      bottomPoint.value = [];
      yignxiangNames = [];

      if (allDays.value) {
        for (const key in allDays.value) {
          if (allDays.value.hasOwnProperty(key)) {
            const dateString = allDays.value[key];
            // 是否是月底
            if (isLastDayOfMonth(dateString)) {
              marks.value[parseInt(key)] = allDays.value[parseInt(key)];
              bottomPoint.value.push(parseInt(key));
            }
          }
        }
      }
      if (sliderValue.value) {
        sliderValue.value.forEach((item) => {
          // console.log(item);
          // const key = getKeyByDate(dayjs(item.createTime).format('YYYYMMDD'));
          const key = getKeyByDate(item.dateDir);
          if (key) {
            if (marks.value[key] == undefined) {
              marks.value[key] = extractChineseOrFirstChars(item.layerName);
            } else {
              marks.value[key] =
                marks.value[key] + '\n' + extractChineseOrFirstChars(item.layerName);
            }
            topPoint.value.push(parseInt(key));
          }
        });
      }
    },
    {
      deep: true,
      // immediate: true,
    },
  );

  // 是否是月底
  function isLastDayOfMonth(dateStr) {
    const date = dayjs(dateStr, 'YYYYMMDD');
    const lastDayOfMonth = date.endOf('month'); // 获取当月最后一天
    return date.isSame(lastDayOfMonth, 'day');
  }

  function getKeyByDate(dateString) {
    for (const key in allDays.value) {
      if (allDays.value.hasOwnProperty(key)) {
        if (allDays.value[key] === dateString) {
          return key;
        }
      }
    }
    return null; // 如果找不到对应的日期字符串，则返回 null
  }

  function extractChineseOrFirstChars(str, numChars = 5) {
    // 查找第一个含有中文字符的部分及其之前的下划线
    const chineseMatch = str.search(/[\u4e00-\u9fa5]/);
    const regexMatch = str.slice(chineseMatch).search(/_/);
    let jxnanme: any = '';
    if (chineseMatch > 0 && regexMatch > 0) {
      // 如果找到了含有中文的部分，返回这部分的前几个字符
      jxnanme = str.substring(chineseMatch, chineseMatch + regexMatch);
    } else if (chineseMatch > 0 && regexMatch < 0) {
      // 如果没有找到含有中文的部分，返回字符串的前几位
      jxnanme = str.substring(chineseMatch, numChars);
    } else {
      jxnanme = str.substring(0, numChars);
    }
    yignxiangNames.push({
      jxnanme: jxnanme,
      name: str,
    });
    return jxnanme;
  }

  function getNameByJxnanme(label) {
    let result: any = '';
    if (label.split('\n').length > 1) {
      let labels = label.split('\n');
      labels.forEach((lab) => {
        yignxiangNames.forEach((item) => {
          if (item.jxnanme == lab) {
            result = result + '<p>' + item.name + '</p>';
          }
        });
      });
    } else {
      yignxiangNames.forEach((item) => {
        if (item.jxnanme == label) {
          result = '<p>' + item.name + '</p>';
        }
      });
    }
    return result;
  }

  function countLines(str, point) {
    // 使用 \n 作为换行符
    // const lines = str.split('\n');
    // console.log(227, topPoint.value);
    let count = 0;
    for (let i = 0; i < topPoint.value.length; i++) {
      if (topPoint.value[i] >= point - 5 && topPoint.value[i] <= point) {
        count++;
      }
    }
    return count;
    // return lines.length;
  }

  const getValue = (key: number) => {
    if (marks.value) {
      return marks.value[key];
      // } else if (allDays.value.hasOwnProperty(key)) {
      //   return allDays.value[key];
      // } else {
      //   return key;
    }
  };

  // 发生改变
  const sliderChange = (key: number) => {
    const keys = Object.keys(allDays.value);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
  };

  // 鼠标滚动
  const handleScroll = (event) => {
    event.preventDefault(); // 阻止默认行为
    // console.log('滚动事件触发:', event.deltaY);
    // 下滚
    if (event.deltaY > 0) {
      // 进度条数据keys
      const keys = Object.keys(allDays.value);
      if (parseInt(keys) + 2 <= Object.keys(allData).length) {
        for (const index in allDays.value) {
          const item = allDays.value[index];
          if (allDays.value[keys[0]] == item && allData[parseInt(index) - 1]) {
            allDays.value[parseInt(index) - 1] = allData[parseInt(index) - 1];
            maxCount.value = maxCount.value + 1;
            minCount.value = minCount.value - 1;
          }
          if (allDays.value[keys[keys.length - 1]] == item && allData[parseInt(index) + 1]) {
            allDays.value[parseInt(index) + 1] = allData[parseInt(index) + 1];
            maxCount.value = maxCount.value + 1;
          }
        }
      }
    }
    // 上滚
    if (event.deltaY < 0) {
      const keys = Object.keys(allDays.value);
      if (keys.length > 2) {
        // 删除最后一个键值对
        const lastKey = keys[keys.length - 1];
        delete allDays.value[lastKey];
        // 删除第一个键值对
        const firstKey = keys[0];
        delete allDays.value[firstKey];
        maxCount.value = maxCount.value - 2;
        minCount.value = minCount.value + 1;
      }
    }
  };

  // 播放/暂停
  const playSwitch = ref(false);
  const handlePlay = () => {
    playSwitch.value = !playSwitch.value;
    if (playSwitch.value && nowValue.value < maxCount.value) {
      addValue();
    }
  };

  function addValue() {
    // console.log(playSwitch.value);
    if (playSwitch.value) {
      setTimeout(() => {
        const keys = Object.keys(allDays.value);
        nowValue.value += 30;
        emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
        addValue();
      }, 3000);
    }
  }

  function getDaysByNowValue() {
    if (nowValue.value != 0) {
      return dayjs(allDays.value[nowValue.value]);
    } else {
      return dayjs(allDays.value[1]);
    }
  }

  // 上一年
  const handleSubYear = () => {
    if (isLeapYear(getDaysByNowValue().year()) && nowValue.value > 58) {
      nowValue.value -= 1;
    }
    if (isLeapYear(getDaysByNowValue().year() - 1) && nowValue.value > 58) {
      nowValue.value += 1;
    }
    calculateDayOfYearAndDates(getDaysByNowValue().add(-1, 'year'));
    const keys = Object.keys(allDays.value);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
    playSwitch.value = false;
  };

  // 上一月
  const handleSubMouth = () => {
    if (nowValue.value <= 31) {
      calculateDayOfYearAndDates(getDaysByNowValue().add(-1, 'month'));
      nowValue.value = parseInt(getDaysByNowValue().add(11, 'month').dayOfYear());
    } else {
      nowValue.value = parseInt(getDaysByNowValue().add(-1, 'month').dayOfYear());
    }
    const keys = Object.keys(allDays.value);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
    playSwitch.value = false;
  };

  // 下一月
  const handleAddMouth = () => {
    if (nowValue.value >= parseInt(dayjs(dayjs().year() + '-12-01').dayOfYear())) {
      calculateDayOfYearAndDates(getDaysByNowValue().add(1, 'month'));
      nowValue.value = parseInt(getDaysByNowValue().add(-11, 'month').dayOfYear());
    } else {
      nowValue.value = parseInt(getDaysByNowValue().add(1, 'month').dayOfYear());
    }
    const keys = Object.keys(allDays.value);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
    playSwitch.value = false;
  };

  // 下一年
  const handleAddYear = () => {
    if (isLeapYear(getDaysByNowValue().year()) && nowValue.value > 58) {
      nowValue.value -= 1;
    }
    if (isLeapYear(getDaysByNowValue().year() + 1) && nowValue.value > 58) {
      nowValue.value += 1;
    }
    calculateDayOfYearAndDates(getDaysByNowValue().add(1, 'year'));
    const keys = Object.keys(allDays.value);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
    playSwitch.value = false;
  };

  /// 判断是否为闰年的函数
  function isLeapYear(y: number): boolean {
    return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
  }

  function calculateDayOfYearAndDates(time) {
    const startDate = dayjs(time).startOf('year');
    const endDate = dayjs(time).endOf('year');
    // 初始化 marks 为空对象
    allData = {};
    allDays.value = {};
    maxCount.value = parseInt(endDate.dayOfYear());
    for (
      let currentDate = startDate;
      currentDate.isBefore(endDate);
      currentDate = currentDate.add(1, 'day')
    ) {
      const dayOfYear = parseInt(currentDate.dayOfYear());
      const dateString = currentDate.format('YYYYMMDD');
      allData[dayOfYear] = dateString;
    }
    allDays.value = cloneDeep(allData);
  }

  // 重置时间轴
  const resetSpin = ref(false);
  function resetTimeLine() {
    resetSpin.value = true;
    calculateDayOfYearAndDates(dayjs());
    nowValue.value = 0;
    maxCount.value = parseInt(dayjs().endOf('year').dayOfYear());
    minCount.value = 1;
    // 播放重置
    playSwitch.value = false;
    setTimeout(() => {
      resetSpin.value = false;
    }, 1000);
    emit('handleNowValueChange', [allDays.value[keys[0]], allDays.value[nowValue.value]]);
  }

  async function fetch() {
    // 历史影像
    GeoTiffManagerLoadPage({
      page: 1,
      limit: 1000000,
    }).then((res) => {
      // console.log(res.items);
      sliderValue.value = res.items;
      calculateDayOfYearAndDates(dayjs());
    });
  }

  onMounted(() => {
    fetch();
  });
</script>
<style lang="less" scoped>
  .timeBox {
    position: relative;
    top: 60px;
    width: 900px;
  }

  .RightBox {
    position: relative;
    top: 40px;
    width: 300px;
  }

  .box-item {
    justify-content: center;
    width: 25px;
    Icon {
      display: flex;
    }
  }
</style>
