<template>
  <div class="box">
    <Title :title="props.title" />
    <div ref="chartRef" class="item" :style="{ height: h + 'px' }"></div>
  </div>
</template>
<script lang="ts" setup>
  import * as echarts from 'echarts';
  import { ref, unref, onMounted, markRaw, watch } from 'vue';
  import { DesktopComponent } from '/@/enums/desktop';
  import { chartProperties } from '../config/properties';
  import { isNumber } from 'min-dash';
  import { useI18n } from '/@/hooks/web/useI18n';
  import useApiRequest from '/@/hooks/event/useApiRequest';
  import Title from '../Title.vue';
  const { changeApiOptions } = useApiRequest();
  const { t } = useI18n();
  const chartRef = ref<HTMLDivElement>();
  const props = withDefaults(
    defineProps<{
      type: DesktopComponent;
      h: number;
      title: string;
      config: any;
    }>(),
    {
      type: DesktopComponent.DEFAULT,
      h: 0,
      title: '',
      config: () => {
        return chartProperties;
      },
    },
  );

  const emit = defineEmits(['update:config']);
  const myEcharts = ref<any>();
  onMounted(async () => {
    await changeData();
    myEcharts.value = markRaw(echarts.init(unref(chartRef) as HTMLDivElement));
    initChart(true);
  });

  watch(
    () => props.h,
    (val) => {
      val && initChart(true);
    },
    {
      deep: true,
    },
  );
  watch(
    () => props.config.renderKey,
    (val) => {
      val && resizeLayout();
    },
    {
      deep: true,
    },
  );
  async function resizeLayout() {
    await changeData();
    initChart(true);
  }
  async function changeData() {
    if (props.config.apiConfig.path) {
      let config = props.config;
      let res = await changeApiOptions(props.config.apiConfig);
      if (res) {
        config.apiData = res;
        config.apiColumns = Object.keys(res);
      }
      if (res.list && Array.isArray(res.list)) {
        config.apiData = res.list;
      }
      if (res.columns && Array.isArray(res.columns)) {
        config.apiColumns = res.columns;
        if (!config.labelKey) config.labelKey = config.apiColumns[0].prop;
        if (!config.valueKey) config.valueKey = config.apiColumns[1].prop;
      }
      emit('update:config', config);
      changeApiData(config);
    }
  }
  function changeApiData(config) {
    // 柱状图
    if (props.type == DesktopComponent.CHARTBAR) {
    }
    // 漏斗图
    if (props.type == DesktopComponent.FUNNEL) {
      let labelKey = 'name';
      if (config.labelKey) {
        labelKey = config.labelKey;
      } else {
        config.labelKey = 'name';
      }
      let valueKey = 'value';
      if (config.labelKey) {
        valueKey = config.valueKey;
      } else {
        config.valueKey = 'value';
      }
      config.echarts.legend.width = config.autoWidth
        ? 'auto'
        : config.echarts.legend.width === 'auto'
        ? 200
        : config.echarts.legend.width;
      if (props.config.echarts && config.echarts.series) {
        config.echarts.series[0].data = config.apiData.map((ele) => {
          return { name: ele[labelKey], value: ele[valueKey] };
        });
      }
      // 图例
      config.echarts.legend.data = config.echarts.series[0].data.map((ele) => {
        return ele.name;
      });
    }
    // 饼图
    if (props.type == DesktopComponent.PIE) {
      config.echarts.legend.width = config.autoWidth
        ? 'auto'
        : config.echarts.legend.width === 'auto'
        ? 200
        : config.echarts.legend.width;
      let labelKey = config.labelKey ? config.labelKey : 'name';
      let valueKey = config.valueKey ? config.valueKey : 'value';
      if (props.config.echarts && config.echarts.series) {
        config.echarts.series[0].data = config.apiData.map((ele, idx) => {
          return {
            name: ele[labelKey],
            value: ele[valueKey],
            selected: idx === config.defaultSelect,
          };
        });
      }
    }
    // 仪表盘
    if (props.type == DesktopComponent.GAUGE) {
      let labelKey = config.labelKey ? config.labelKey : 'name';
      let valueKey = config.valueKey ? config.valueKey : 'value';
      if (config.echarts && config.echarts.series && config.echarts.series[0]) {
        // 仪表盘只显示第一条数据
        config.echarts.series[0].data = config.apiData
          .filter((_, i) => i === 0)
          .map((ele) => {
            return { name: ele[labelKey], value: isNumber(ele[valueKey]) ? ele[valueKey] : 0 };
          });
      }
    }
    // 雷达图
    if (props.type == DesktopComponent.RADAR) {
      // 根据指标来显示数据
      config.echarts.legend.data = [];
      config.echarts.series[0].data = [];
      if (props.config.apiData.length > 0) {
        config.apiData.map((ele) => {
          config.echarts.series[0].data.push({
            value: [],
            name: ele[config.labelKey],
          });
          config.echarts.legend.data.push(ele[config.labelKey]);
        });

        if (config.echarts && config.echarts.radar && config.echarts.radar.indicator) {
          config.echarts.radar.indicator.forEach((element) => {
            if (element.value && config.echarts.series[0].data) {
              if (config.apiData.length > 0) {
                config.apiData.map((ele) => {
                  let idx = config.echarts.series[0].data.findIndex((o) => {
                    return o.name == ele.name;
                  });
                  if (idx >= 0) {
                    config.echarts.series[0].data[idx].value.push(ele[element.value]);
                  }
                });
              }
            }
          });
        }
      }
    }
    emit('update:config', config);
  }
  /**
   * 初始化echart
   * @param clearCaching 是否清除缓存
   */
  const initChart = (clearCaching = false) => {
    myEcharts.value.showLoading({
      text: t('加载中'),
      color: '#5e95ff',
      textColor: 'rgba(255, 255, 255, 0.6)',
      maskColor: 'rgba(255, 255, 255, 0.2)',
      zlevel: 0,
    });
    setTimeout(() => {
      myEcharts.value.hideLoading();
      if (myEcharts.value) {
        myEcharts.value.setOption(props.config.echarts, clearCaching);
        myEcharts.value.resize();
      }
    }, 100);
  };
</script>
<style lang="less" scoped>
  .box {
    width: 100%;
    height: 100%;
    padding-top: 40px;

    .item {
      height: 100%;
      width: 100%;
      -webkit-tap-highlight-color: transparent;
      user-select: none;
      position: relative;
    }
  }
</style>
