<script setup lang="ts">
import { Ref, defineProps, watchEffect, watch } from "vue";
import type { EChartsOption } from "echarts";
import { useECharts } from "@/hooks/web/useECharts";
import { colorList, mergeOptions } from "@/components/chart/options/index";
import { registerMap } from "echarts";
import { isObject } from "@/utils/is";
import useEchartsAutoTooltip from "@/components/chart/logic/useEchartsAutoTooltip";
import { getThemeColor } from "@/components/chart/options/theme";
import { mapMapping, getNearPointData } from "@/assets/map/provinceData";
const mapData = mapMapping();
const yaTheme = localStorage.getItem("YA_THEME");
const chartRef = ref<HTMLDivElement | null>(null);
let stopAutoShowFun = null as any;
const { setOptions, getInstance, echarts } = useECharts(
  chartRef as Ref<HTMLDivElement>
);

interface MapChartProps {
  title?: string;
  /**
   * 图表数据
   */
  chartData: any[];
  chartDataTwo: any[];
  tooltipFormatter?:
    | string
    | ((params: any, ticket: any, callback: any) => string);
  /**
   * 是否需要手动设置一些其它的设置，需要结合otherOptions才能起作用
   */
  manual?: boolean;
  /**
   * 手动设置一些其它的设置，需要结合manual才能起作用
   */
  otherOptions?: EChartsOption;
  /**
   * 是否开启自动轮播
   */
  autotip?: boolean;
  makePoint?: boolean;
  twoMakePoint?: boolean;
  showMakeOne?: boolean;
  colorPoint?: string;
  zoom?: number;
}

const {
  title = "",
  chartData = [],
  chartDataTwo = [],
  tooltipFormatter = "",
  manual = false,
  otherOptions = {},
  autotip = false,
  makePoint = false,
  twoMakePoint = false,
  showMakeOne = false,
  colorPoint,
  zoom = 1,
} = defineProps<MapChartProps>();

const MAP_COLOR = {
  areaColor: yaTheme === "light" ? "#fff" : "transparent",
  borderColor: yaTheme === "light" ? "rgba(38,73,106,0.65)" : "#4A9DD7",
  shadowColor: yaTheme === "light" ? "rgba(0,149,255,0.08)" : "#17567C",
  labelColor: yaTheme === "light" ? "rgba(0,0,0,0.4)" : "#FFFFFF",
  emphasisLabelColor:
    yaTheme === "light" ? "#0095FF" : "rgba(255, 255, 255, 1)",
  emphasisAreaColor: yaTheme === "light" ? "#c7e8ff" : "rgba(145, 140, 73, 1)",
  emphasisBorderColor: "rgba(255, 222, 65, 1)",
  selectedAreaColor: "rgba(240, 187, 36, .5)",
  selectedBorderColor: "rgba(240, 187, 36, 1)",
  selectedLabelColor: "rgba(255, 255, 255, 1)",
};

let options: EChartsOption = {
  tooltip: {
    trigger: "item",
    position: "inside",
    confine: true,
    backgroundColor: "transparent",
    extraCssText:
      "z-index: 9;border-radius: 0; border: 0;padding: 0;background: red;margin: 0;min-width: 0;height: 0;",
    formatter: unref(tooltipFormatter) as any,
  },

  // geo: {
  //   map: 'ShanDong',
  //   aspectScale: 1,
  //   roam: false,
  //   zoom: 1,
  //   itemStyle: {
  //     areaColor: MAP_COLOR.areaColor,
  //     borderColor: MAP_COLOR.borderColor,
  //     shadowColor: MAP_COLOR.shadowColor,
  //     shadowOffsetX: 0,
  //     shadowOffsetY: 10,
  //     shadowBlur: 1
  //   }
  // },

  series: [
    {
      type: "map",
      map: "ShanDong",
      geoIndex: 1,
      aspectScale: 0.85,
      zoom: zoom || 1,
      labelLayout(params) {
        return {
          x: params.rect.x + params.rect.width / 2,
          y: params.rect.y + params.rect.height / 2,
          verticalAlign: "middle",
          align: "center",
        };
      },
      label: {
        show: true,
        color: MAP_COLOR.labelColor,
        fontSize: 10,
        lineHeight: 15,
        rich: {},
      },

      itemStyle: {
        areaColor: MAP_COLOR.areaColor,
        borderColor: MAP_COLOR.borderColor,
        shadowColor: MAP_COLOR.shadowColor,
      },

      emphasis: {
        itemStyle: {
          areaColor: MAP_COLOR.selectedAreaColor,
          borderColor: MAP_COLOR.emphasisBorderColor,
          shadowColor: MAP_COLOR.shadowColor,
        },
        label: {
          color: MAP_COLOR.emphasisLabelColor,
        },
      },

      select: {
        itemStyle: {
          areaColor: MAP_COLOR.selectedAreaColor,
          borderColor: MAP_COLOR.emphasisBorderColor,
          shadowColor: MAP_COLOR.shadowColor,
        },
        label: {
          color: MAP_COLOR.emphasisLabelColor,
        },
      },
      data: [],
    },
  ],
};

const getMakePointData = (type, list) => {
  if (list.length === 0) return [];
  const iconMax = 35;
  let iconSize, maxCount, _symbolSize, percentage;
  maxCount = Math.max(
    ...list.map((item: any) => (type ? item.value : item.value))
  );
  const data = list.map((item: any) => {
    let city;
    let areaCoord;
    if (unref(showMakeOne)) {
      areaCoord = mapData.coord;
    } else {
      areaCoord = getNearPointData(mapData.coord);
    }
    if (type) {
      city = mapData.coord.find((city: any) => city.name === item.name);
      if (item.percentage) {
        percentage = item.percentage;
      }
    } else {
      city = areaCoord.find((city: any) => city.name === item.name);
      if (item.percentageTwo) {
        percentage = item.percentageTwo;
      }
    }
    iconSize = Math.floor(
      type ? item.value : (item.value / maxCount) * iconMax
    );
    _symbolSize = [3, iconSize];
    const len = parseFloat(percentage.replace("%", ""));
    const cityCenter = JSON.parse(JSON.stringify(city.center));
    cityCenter[1] += len / 277;
    return {
      name: item.name,
      coord: cityCenter,
      value: type ? item.value : item.value,
      percentage: percentage,
      symbolSize: (rawValue, params) => {
        if (!twoMakePoint) {
          if (params.data.percentage) {
            let H = Number(params.data.percentage.replace("%", "")) / 1;
            return [3, Math.max(H / 2, 3)];
          } else {
            return _symbolSize;
          }
        } else {
          if (item.valuePercent) {
            return [3, Math.max(item.valuePercent, 3)];
          } else if (params.data.percentage) {
            let H = Number(params.data.percentage.replace("%", "")) / 1;
            return [3, Math.max(H / 2, 3)];
          }
        }
      },
    };
  });
  return data;
};

const getMakePoint = () => {
  let markPoint = {
    show: false,
    symbol: "roundRect",
    itemStyle: {
      color:
        unref(colorPoint) ||
        (getThemeColor().colorList && getThemeColor().colorList[0]),
    },
    label: {
      show: false,
    },
    data: [],
  } as any;
  markPoint.data = getMakePointData(true, unref(chartData));
  if (markPoint.data.length > 0) {
    markPoint.show = true;
  }
  return markPoint;
};
const getMakePoint1 = () => {
  let markPoint = {
    show: false,
    symbol: "roundRect",
    itemStyle: {
      color:
        (getThemeColor().colorList && getThemeColor().colorList[1]) ||
        "#8D92FF",
    },
    label: {
      show: false,
    },
    data: [],
  } as any;
  markPoint.data = getMakePointData(false, unref(chartDataTwo));
  if (markPoint.data.length > 0) {
    markPoint.show = true;
  }
  return markPoint;
};

const initChart = async () => {
  registerMap("ShanDong", mapData.coordjson);
  // @ts-ignore
  options.tooltip!.formatter = unref(tooltipFormatter);
  options.series![0].data = unref(chartData);

  if (unref(makePoint)) {
    const makeStyle = getMakePoint();
    options.series![0].markPoint = getMakePoint();
  }
  if (unref(twoMakePoint)) {
    let arr = JSON.parse(JSON.stringify(options.series![0]));
    arr.data = unref(chartDataTwo);
    options.series![1] = arr;
    options.series![1].markPoint = getMakePoint1();
  }
  // 如果是手动设置模式的话
  if (unref(manual) && isObject(unref(otherOptions))) {
    options = mergeOptions(options, unref(otherOptions));
  }
  if (unref(chartData).length > 0) {
    if (unref(autotip)) {
      openAutoTooltip();
    }
  }
  setOptions(options);
};
watch(
  () => chartData,
  (val, preVal) => {
    initChart();
  }
);
// watchEffect(() => {
//   if(unref(chartData).length === 0) return;
//   initChart()
// })

function openAutoTooltip() {
  const instance = getInstance();
  const { stopAutoShow } = useEchartsAutoTooltip(instance, options);
  stopAutoShowFun = stopAutoShow;
}

onMounted(() => {
  initChart();
});
onUnmounted(() => {
  stopAutoShowFun && stopAutoShowFun();
});
</script>

<template>
  <div
    class="chart"
    ref="chartRef"
    :style="{ width: '100%', height: '100%' }"
  ></div>
</template>

<style lang="scss">
.light-map-tip-box {
  min-width: 155px;
  padding: 12px 16px;
  box-sizing: border-box;
  background: rgba(9, 103, 138, 0.8);
  box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
}

.light-map-tip-box-name {
  font-size: 12px;
  font-weight: 600;
  color: #fff;
}

.light-map-tip-box-content {
  width: 100%;
  display: flex;
  flex-direction: column;
  color: #fff;
}

.light-map-tip-box-item {
  display: flex;
  align-items: center;
  font-size: 12px;
  justify-content: space-between;
  width: 100%;
  .light-map-tip-box-item-label {
    font-size: 12px;
    font-weight: 400;
  }

  .light-map-tip-box-value {
    font-size: 12px;
  }
}

.light-map-tip-box-item.mt-12 {
  margin-top: 12px;
}
</style>
