<template>
  <div style="position: relative;">
    <div ref="chartRef" style="height: 620px; width: 1640px" @click="handleClick"></div>
    <!-- <div
      v-show="tooltipVisible"
      class="custom-tooltip background-as-card"
      :style="{ left: mouseX + 'px', top: mouseY + 'px', cursor: dragging ? 'move' : 'default' }"
      @mousedown="startDrag"
    >
      <div
      class="tooltip-header flex-display"
      @mousedown.stop="startDrag"
      style="cursor: move;"
      >
      <div class="tooltip-header-left text-title-3-bold">{{ currentDate }}</div>
      <div class="tooltip-header-right text-title-3-show">{{ `${'3个部门'}/${'3项举措'}` }}</div>
      </div>
      <div class="tooltip-main">
      <div class="tooltip-main-item" v-for="item, index in currentDetailList" :key="index">
        <div class="item-header flex-display">
        <div class="item-header-left flex-display">
          <div class="logo">
          <img style="width:100%; height: 100%" :src="item.orgLogoUrl" alt="logo">
          </div>
          <div class="name text-bold">{{ item.orgName }}</div>
          <div class="status">
          <div class="status-on text-tip-2" v-if="item.stauts === 2">{{ '已落实' }}</div>
          <div class="status-off text-tip-2" v-else>{{ '未落实' }}</div>
          </div>
        </div>
        <div class="item-header-right  flex-display">
          <AreaTag v-for="tag, idx in item.techDomainList.slice(0, 3)" :key="idx" :tagName="tag"></AreaTag>
        </div>
        </div>
        <div class="item-content text-compact">{{ item.name }}</div>
        <div class="item-footer"></div>
      </div>
      </div>
    </div> -->
    <el-dialog v-model="tooltipVisible" width="1298px">
      <div class="tooltip-header flex-display">
        <div class="tooltip-header-left text-title-3-bold">{{ currentDate }}</div>
        <div class="tooltip-header-right text-title-3-show">{{ `涉及${currentDetailList.length}项行政令` }}
        </div>
      </div>
      <div class="tooltip-main">
        <div class="tooltip-main-item" v-for="item, index in currentDetailList" :key="index">
          <div class="item-main-header flex-display" @click="handleToDetail(item)">
            <div class="item-main-header-left">
              <div class="item-main-header-type color-bg-active text-tip-1 main-color">{{ '政令' }}</div>
              <div class="text-title-3-bold main-color">{{ item.administrativeOrderInfoTitle }}</div>
            </div>
            <div class="item-main-header-right text-tip-1-bold main-color">
              {{ `涉及${item.orgNum}个部门` }}
            </div>
          </div>
          <div class="item-list">
            <div class="item-list-item flex-display" v-for="val, idx in item.innerList" :key="idx">
              <div class="item-list-left flex-display">
                <div class="id text-bold main-color color-bg-active">{{ idx + 1 }}</div>
                <div class="info">
                  <div class="content text-regular text-primary-80-clor">{{ val.name }}</div>
                  <div class="area-box flex-display">
                    <AreaTag v-for="tag, tagIdx in val.techDomainList" :key="tagIdx" :tagName="tag"></AreaTag>
                  </div>
                </div>
              </div>
              <div class="item-list-right ">
                  <div class="right-list-item flex-display" v-for="org, orgIdx in val.orgList" :key="orgIdx">
                    <div class="org-box flex-display">
                      <div class="logo">
                        <img style="width: 100%; height: 100%;" :src="org.orgLogoUrl" alt="">
                      </div>
                      <div class="org-name text-tip-1 text-primary-80-clor">{{ org.orgName }}</div>
                    </div>
                    <div class="status">
                                        <div class="status-on text-tip-2" v-if="org.stauts === 2">{{ '已落实' }}</div>
                  <div class="status-off text-tip-2" v-else>{{ '未落实' }}</div>
                    </div>

                  </div>
              </div>
            </div>




            <!-- <div class="item-header flex-display">
              <div class="item-header-left flex-display">
                <div class="logo">
                  <img style="width:100%; height: 100%" :src="val.orgLogoUrl" alt="logo">
                </div>
                <div class="name text-primary-80-clor text-bold">{{ val.orgName }}</div>
                <div class="status">
                  <div class="status-on text-tip-2" v-if="val.stauts === 2">{{ '已落实' }}</div>
                  <div class="status-off text-tip-2" v-else>{{ '未落实' }}</div>
                </div>
              </div>
              <div class="item-header-right  flex-display">
                <AreaTag v-for="tag, idxx in val.techDomainList.slice(0, 3)" :key="idxx" :tagName="tag"></AreaTag>
              </div>
            </div>
            <div class="item-content text-compact">{{ val.name }}</div> -->
          </div>


        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue';
import router from "@/router";
import * as echarts from 'echarts/core';
import { CustomChart } from 'echarts/charts';
import { TitleComponent, TooltipComponent, CalendarComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';


dayjs.locale('zh-cn');

const props = defineProps(
  {
    timelineData: {
      type: Array,
      default: []
    }
  }
);

const dragging = ref(false);
let dragOffsetX = 0;
let dragOffsetY = 0;

const startDrag = (e) => {
  dragging.value = true;
  dragOffsetX = e.clientX - mouseX.value;
  dragOffsetY = e.clientY - mouseY.value;

  document.addEventListener('mousemove', onDrag);
  document.addEventListener('mouseup', stopDrag);
}

const onDrag = (e) => {
  if (dragging.value) {
    mouseX.value = e.clientX - dragOffsetX;
    mouseY.value = e.clientY - dragOffsetY;
  }
}

const stopDrag = () => {
  dragging.value = false;
  document.removeEventListener('mousemove', onDrag);
  document.removeEventListener('mouseup', stopDrag);
}


echarts.use([
  CustomChart,
  TitleComponent,
  TooltipComponent,
  CalendarComponent,
  CanvasRenderer,
]);

const chartRef = ref(null);
let chartInstance = null;

// 弹窗控制
const tooltipVisible = ref(false)
const mouseX = ref(0)
const mouseY = ref(0)
const currentDate = ref('')
const currentDetailList = ref([])
const currentOrgNum = ref(0)

// // 鼠标移动，记录位置
const handleMouseMove = (e) => {
  mouseX.value = e.clientX + 20
  mouseY.value = e.clientY - 20
}

const handleClick = (e) => {
  // mouseX.value = e.clientX - 160
  // mouseY.value = e.clientY - 120
  mouseX.value = e.clientX + 10
  mouseY.value = e.clientY - 100

}

// 计算展示的月份  获取今天在内的之后的三个月的月份
const startDate = dayjs();
console.log('startDate', startDate);

const months = [0, 1, 2].map(offset => startDate.add(offset, 'month'));

// 生成日历数据
function buildDataMap(arr) {
  const map = new Map();
  const stats = months.map(() => ({ total: 0, resolved: 0 }));

  // 按日期聚合
  arr.forEach(item => {
    const date = item.endDate;
    if (!map.has(date)) {
      map.set(date, {
        date,
        count: 0,
        resolved: 0,
        logos: [],
        status: 'empty',
        raw: [],
      });
    }
    const d = map.get(date);
    // d.count += 1;
    // 按 administrativeOrderInfoTitle 去重计数
    if (!d._titleSet) d._titleSet = new Set();
    if (item.administrativeOrderInfoTitle && !d._titleSet.has(item.administrativeOrderInfoTitle)) {
      d._titleSet.add(item.administrativeOrderInfoTitle);
      d.count += 1;
    }
    if (item.status === 2) d.resolved += 1;
    if (d.logos.length < 3 && item.orgLogoUrl) d.logos.push(item.orgLogoUrl);
    d.status = 'has_events';
    d.raw.push(item);
  });

  // 统计每月
  months.forEach((month, idx) => {
    const daysInMonth = month.daysInMonth();
    for (let i = 1; i <= daysInMonth; i++) {
      const dateStr = month.date(i).format('YYYY-MM-DD');
      const d = map.get(dateStr);
      if (d) {
        stats[idx].total += d.count;
        stats[idx].resolved += d.resolved;
      } else {
        map.set(dateStr, {
          date: dateStr,
          count: 0,
          resolved: 0,
          logos: [],
          status: 'empty',
          raw: [],
        });
      }
    }
  });

  return { dataMap: map, monthStats: stats };
}

console.log('timelineData', props.timelineData);

// const calendarWidthPercent = 35;
// const gapPercent = (80 - (calendarWidthPercent * 3)) / 4;


const { dataMap, monthStats } = buildDataMap(props.timelineData);


function getOption() {
  const calendarWidthPercent = 27;
  // const gapPercent = (90 - (calendarWidthPercent * 3)) / 4;
  const gapPercent = 0.02;

  // 修正每个calendar之间的间隙为0，且calendar宽度撑满
  // 由于echarts calendar的cellSize为['auto', 82]，但宽度受calendar宽度影响
  // 这里强制每个calendar的left分别为0%、33.33%、66.66%，宽度33.33%

  // 计算所有天的最大 count
  let maxCount = 0;
  dataMap.forEach(item => {
    if (item.count > maxCount) maxCount = item.count;
  });

  // 颜色插值函数
  function getColorByCount(count) {
    // rgb(231,243,255) -> rgb(137,193,255)
    const start = [231, 243, 255];
    const end = [137, 193, 255];
    if (maxCount === 0) return `rgb(${start.join(',')})`;
    const ratio = Math.min(count / maxCount, 1);
    const rgb = start.map((s, i) => Math.round(s + (end[i] - s) * ratio));
    return `rgb(${rgb.join(',')})`;
  }

  const calendars = months.map((month, index) => ({
    top: 40,
    left: `${gapPercent + index * (calendarWidthPercent + gapPercent)}%`,
    // width: `${calendarWidthPercent}%`,
    range: month.format('YYYY-MM'),
    cellSize: [110, 80],
    splitLine: { show: true, lineStyle: { color: '#fff', width: 2 } },
    itemStyle: { color: '#f0f9ff', borderColor: 'rgb(5, 95, 194)', borderWidth: 4 },
    yearLabel: { show: false },
    monthLabel: { show: false },
    dayLabel: { show: false },
    // monthLabel: {
    //   margin: 5 // 调整月份标签的边距 [citation:7]
    // }
    // top: 40,
    // left: 50,
    // right: 50,
    // cellSize: ['auto', 'auto'], // 设置为固定的整数尺寸，避免因小数产生间隙
    // range: month.format('YYYY-MM'),  // 显示2024年1月
    // itemStyle: {
    //   borderWidth: 0,  // 关键：将边框宽度设为0
    //   // 可以设置其他样式，如格子的颜色
    //   color: '#f0f0f0'
    // },
    // // 如果需要，可以进一步调整标签与格子的距离，避免标签造成的间隙错觉
    // dayLabel: {
    //   margin: 5 // 调整天数标签的边距 [citation:7]
    // },
    // monthLabel: {
    //   margin: 5 // 调整月份标签的边距 [citation:7]
    // }
  }));

  const titles = months.map((month, index) => ({
    // text: `{month|${month.format('M月')}}                                         {stats|共 ${monthStats[index].total} 项, 已落实 ${monthStats[index].resolved} 项}`,
    text: index === 0 ? `{month|${month.format('M月')}}                                                              {stats|共 ${monthStats[index].total} 项, 已落实 0 项}` : `                     {month|${month.format('M月')}}                                            {stats|共 ${monthStats[index].total} 项, 已落实 0 项}`,
    left: `${gapPercent + index * (calendarWidthPercent + gapPercent)}%`,
    top: 10,
    textStyle: {
      rich: {
        month: {
          fontSize: 18,
          fontWeight: 'bold',
          color: 'rgb(5, 95, 194)',
          fontFamily: 'Source Han Sans CN'
        },
        stats: {
          fontSize: 18,
          color: 'rgb(5, 95, 194)',
          fontWeight: 'bold',
          fontFamily: 'Source Han Sans CN'
        }
      }
    }
  }));

  const series = months.map((month, index) => {
    const monthData = [];
    const daysInMonth = month.daysInMonth();
    for (let i = 1; i <= daysInMonth; i++) {
      const dateStr = month.date(i).format('YYYY-MM-DD');
      const item = dataMap.get(dateStr);
      monthData.push([dateStr, item]);
    }

    return {
      type: 'custom',
      coordinateSystem: 'calendar',
      calendarIndex: index,
      data: monthData,
      renderItem: (params, api) => {
        const cellPoint = api.coord([api.value(0), 0]);
        const cellWidth = params.coordSys.cellWidth;
        const cellHeight = params.coordSys.cellHeight;
        const dataIndex = params.dataIndex;
        const rawDataItem = monthData[dataIndex];
        const item = rawDataItem[1];
        if (!item) return;

        const x = cellPoint[0] - cellWidth / 2;
        const y = cellPoint[1] - cellHeight / 2;

        const groupChildren = [];
        // 动态颜色
        const bgColor = item.status === 'has_events'
          ? getColorByCount(item.count)
          : '#f0f9ff';

        groupChildren.push({
          type: 'rect',
          shape: { x, y, width: cellWidth, height: cellHeight },
          style: {
            fill: bgColor,
            stroke: '#fff',
            lineWidth: 1
          },
        });

        if (item.status === 'has_events') {
          const iconSize = 20;
          const iconGap = -5;
          const maxIcons = 3;
          const displayLogos = Array.from(new Set(item.logos)).slice(0, maxIcons);
          const iconsY = y + 8;
          const iconsX = x + 8;

          displayLogos.forEach((logo, idx) => {
            groupChildren.push({
              type: 'image',
              style: {
                image: logo,
                x: iconsX + idx * (iconSize + iconGap),
                y: iconsY,
                width: iconSize,
                height: iconSize,
              },
            });
          });

          groupChildren.push({
            type: 'text',
            style: {
              text: `${item.count}项行政令`,
              x: x + 8,
              y: y + cellHeight - 12,
              textAlign: 'left',
              textVerticalAlign: 'bottom',
              fontSize: 18,
              fontFamily: 'Source Han Sans CN'
            },
          });
        } else {
          const d = dayjs(item.date);
          groupChildren.push({
            type: 'text',
            style: {
              text: d.format('YYYY年'),
              x: x + cellWidth / 2,
              y: y + cellHeight / 2 - 8,
              textAlign: 'center',
              textVerticalAlign: 'bottom',
              fontSize: 10,
              fill: 'rgb(185, 220, 255)',
              fontFamily: 'Source Han Sans CN'
            },
          });
          groupChildren.push({
            type: 'text',
            style: {
              text: d.format('MM月DD日'),
              x: x + cellWidth / 2,
              y: y + cellHeight / 2 + 4,
              textAlign: 'center',
              textVerticalAlign: 'top',
              fontSize: 12,
              fill: 'rgb(185, 220, 255)',
              fontFamily: 'Source Han Sans CN'
            },
          });
        }

        return {
          type: 'group',
          children: groupChildren,
        };
      },
    };
  });

  return {
    tooltip: { show: false },
    title: titles,
    calendar: calendars,
    series: series,
  };
}

// 点击政令，跳转详情
const handleToDetail = (item) => {
  console.log('item', item);
  
  const path = "/decreeLayout/overview/introduction";
  const query = { id: item.orderId };
  const route = router.resolve({ path, query });
  window.open(route.href, "_blank");
}

onMounted(() => {
  if (chartRef.value) {
    chartInstance = echarts.init(chartRef.value, undefined, { renderer: 'canvas' });
    chartInstance.setOption(getOption());
    window.addEventListener('resize', resizeChart);

    chartInstance.on('click', (params) => {
      console.log('params', params);

      if (Array.isArray(params.data) && params.data.length >= 2) {
        const date = params.data[0]
        // const list = dataMap.get(date)?.raw || []
        const list = params.data[1].raw
        if (list.length > 0) {
          currentDate.value = date
          // 按 administrativeOrderInfoTitle 分类
          // const grouped = [];
          // const map = new Map();
          // 按 sanctionId 分类，sanctionId 相同合为一个元素，形式为 { name: 'xxx', info: {} }
          const grouped = [];
          const titleMap = new Map();
          list.forEach(item => {
            const title = item.administrativeOrderInfoTitle || '';
            if (!titleMap.has(title)) {
              titleMap.set(title, { administrativeOrderInfoTitle: title, innerList: [], orgNum: 0, orderId: item.orderId });
              grouped.push(titleMap.get(title));
            }
            // 统计 orgNum
            const group = titleMap.get(title);
            // 用 Set 统计不同 orgName
            if (!group._orgSet) group._orgSet = new Set();
            group._orgSet.add(item.orgName);
            group.orgNum = group._orgSet.size;

            // 按 sanctionId 分类
            const innerList = titleMap.get(title).innerList;
            let sanctionGroup = innerList.find(g => g.sanctionId === item.sanctionId);
            if (!sanctionGroup) {
              sanctionGroup = {
                sanctionId: item.sanctionId,
                name: item.name,
                techDomainList: item.techDomainList || [],
                orgList: [],
                info: []
              };
              innerList.push(sanctionGroup);
            }
            sanctionGroup.orgList.push({
              orgName: item.orgName,
              orgLogoUrl: item.orgLogoUrl,
              status: item.status
            });
            sanctionGroup.info.push({ ...item });
          });
          currentDetailList.value = grouped;
          console.log('currentDetailList', currentDetailList.value);

          tooltipVisible.value = true
        } else {
          tooltipVisible.value = false
        }
      }
    });

    // chartInstance.on('mouseout', () => {
    //   tooltipVisible.value = false
    // });
  }
});

function resizeChart() {
  if (chartInstance) {
    chartInstance.resize();
  }
}

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeChart);
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});
</script>

<style scoped>
.custom-tooltip {
  position: fixed;
  /* 使用 fixed 相对于视口定位 */
  /* pointer-events: none; */
  /* 让鼠标事件穿透到图表，避免闪烁 */
  z-index: 1000;
  width: 1278px;
  background: rgb(255, 255, 255);

}

.tooltip-header {
  height: 56px;
  box-sizing: border-box;
  padding: 12px 24px;
  justify-content: space-between;
  border-bottom: 1px solid rgb(234, 236, 238);
}

.tooltip-header-left{
  margin-top: 10px;
}

.tooltip-header-right{
  height: 34px;
  background: rgba(206, 79, 81, 0.1);
  border-radius: 17px;
  color: rgba(206, 79, 81);
  padding: 5px 12px;
}

/* .tooltip-main {
  padding: 0 24px 10px;

} */

.tooltip-main-item {
  padding: 10px 0;
  width: 1254px;
  /* height: 144px; */
  border-bottom: 1px solid rgb(234, 236, 238);
}

.item-header {
  height: 46px;
  justify-content: space-between;
  align-items: center;
}

.item-header-left {
  gap: 8px;
  align-items: center;

}

.item-list-item{
  padding: 12px 12px 16px 20px;
    border-bottom: 1px solid rgb(234, 236, 238);
}

.item-list-left{
  width: 848px;

}

.area-box {
  margin-top: 8px;
  gap: 8px;
}

.id{
  width: 30px;
  height: 30px;
  border-radius: 15px;
  text-align: center;
  line-height: 30px;
}
.info{
  width: 800px;
}

.item-list-right{
  width: 356px;
  justify-content: space-between;
}

.right-list-item {
  justify-content: space-between;
  margin-bottom: 8px;
}

.org-box {
  gap: 8px;
}

.org-name{
  width: 234px;
}

.logo {
  width: 24px;
  height: 24px;
}

.status-on {
  height: 23px;
  padding: 0 8px;
  color: rgb(33, 129, 57);
  background: rgba(33, 129, 57, 0.1);
}

.status-off {
  height: 23px;
  padding: 0 8px;
  color: rgb(206, 79, 81);
  background: rgba(206, 79, 81, 0.1);
}


.item-header-right {
  gap: 8px;
}

.item-main-header {
  width: 1254px;
  height: 68px;
  padding: 0 8px;
  border-radius: 4px;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  border-bottom: 1px solid rgb(234, 236, 238);
}

.item-main-header-left {
  display: flex;
  gap: 8px;
  align-items: center;
}

.item-main-header-type {
  height: 28px;
  border-radius: 4px;
  padding: 0 8px;
  line-height: 28px;
  text-align: center;
}
</style>
