import { defineComponent, computed, ref, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import dayjs from "@/utils/dayjs";
import * as echarts from "echarts";

import { getSortAreaDataByHour } from "./fetchData";
import { RoadInfoByDate, AreaInfoByHour, EnumModes } from "../../../store/roadUnit/types";
import { areaInfoOccByHourOption, areaInfoSpeedByHourOption } from "./chartOptions";

import { useStore } from "@/hook/useStore";
import useRoadUnitStore from "@/store/roadUnit";

import style from "@/assets/style/RoadUnit/areaInfo.module.less";

export default defineComponent({
  setup() {
    const router = useRouter();
    const route = useRoute();

    /**
     * 当前模式：occ/speed
     * 区域名称
     * 所选日期
     * 区域通行车辆、车次、车速分日表
     */
    const { mode, area: areaName, time: date, areaInfoByDate } = useStore(useRoadUnitStore);

    /**
     * 区域总车次
     */
    const TotalOcc = computed(() =>
      areaInfoByDate.value.reduce((acc, cur) => {
        return acc + cur.pass_veh_occ;
      }, 0)
    );

    /**
     * 区域总车辆
     */
    const TotalNum = computed(() =>
      areaInfoByDate.value.reduce((acc, cur) => {
        return acc + cur.pass_veh_num;
      }, 0)
    );

    /**
     * 区域平均速度
     */
    const averageSpeed = computed(() =>
      parseFloat(
        (
          areaInfoByDate.value.reduce((acc, cur) => {
            return acc + cur.pass_veh_occ * cur.mean_velocity;
          }, 0) / TotalOcc.value
        ).toFixed(2)
      )
    );

    /**
     * 获取并渲染区域通行车辆、车次、车速分时表
     * AreaInfo页面的车次、车速趋势chart
     * 初始时执行一次，然后每次区域或时间更改时，都会执行
     */
    const areaInfoByHour = ref<AreaInfoByHour[]>([]);
    const getAreaInfoByHour = async () => {
      try {
        const startTime = dayjs(date.value, "YYYY-MM-DD").format("YYYY-MM-DD HH:mm:ss");
        const endTime = dayjs(date.value, "YYYY-MM-DD").add(1, "day").format("YYYY-MM-DD HH:mm:ss");
        areaInfoByHour.value = await getSortAreaDataByHour(startTime, endTime, areaName.value);
      } catch (e) {
        console.error(e);
      }
    };
    getAreaInfoByHour();
    watch([date, areaName], () => {
      getAreaInfoByHour();
    });

    /**
     * 渲染图表
     */
    const chart = ref<HTMLDivElement>();
    let chartInstance: echarts.ECharts;
    const renderChart = () => {
      if (areaInfoByHour.value.length > 0) {
        const lineData = [] as any[],
          times = [] as any[];
        let max = 0;
        areaInfoByHour.value.forEach((item) => {
          lineData.push(mode.value === EnumModes.occ ? item.pass_veh_occ : item.mean_velocity);
          times.push(dayjs(item.count_time, "YYYY-MM-DD HH:mm:ss").format("HH"));
          max =
            mode.value === EnumModes.occ
              ? max > item.pass_veh_occ
                ? max
                : item.pass_veh_occ
              : max > item.mean_velocity
              ? max
              : item.mean_velocity;
        });
        const option = mode.value === EnumModes.occ ? areaInfoOccByHourOption : areaInfoSpeedByHourOption;
        option.xAxis.data = times;
        option.series[0].data = lineData;
        option.yAxis.max = max;
        option.yAxis.interval = max / 4 < 10 ? 10 : Math.ceil(max / 4 / 10) * 10;

        const container = chart.value;
        if (container) {
          chartInstance || (chartInstance = echarts.init(container));
          chartInstance.setOption(option);
        }
      }
    };
    onMounted(() => {
      renderChart();
    });
    watch([mode, areaInfoByHour], () => {
      renderChart();
    });

    /**
     * 排序渲染列表等数据
     */
    const getRenderListData = (data: RoadInfoByDate[]) => {
      if (mode.value === EnumModes.speed) {
        return data.sort((a, b) => {
          return b.mean_velocity - a.mean_velocity;
        });
      } else {
        return data.sort((a, b) => {
          return b.pass_veh_occ - a.pass_veh_occ;
        });
      }
    };

    // 选中某一条路
    const handleClick = (item: RoadInfoByDate) => {
      router.replace({
        path: route.path,
        query: {
          ...route.query,
          road: item.road_name,
        },
      });
    };

    return () => (
      <div class={style.area}>
        {mode.value === EnumModes.occ ? (
          <div class={style.statistics}>
            <div>
              <span class={style.title}>总通行车辆数</span>
              <div>
                <span class={style.count}>{TotalNum.value}</span>
                <span class={style.unit}>辆</span>
              </div>
            </div>
            <div>
              <span class={style.title}>总通行车次</span>
              <div>
                <span class={style.count}>{TotalOcc.value}</span>
                <span class={style.unit}>车次</span>
              </div>
            </div>
          </div>
        ) : (
          <div class={style.statistics}>
            <div>
              <span class={style.title}>平均车速</span>
              <div>
                <span class={style.count}>{averageSpeed.value}</span>
                <span class={style.unit}>km/h</span>
              </div>
            </div>
          </div>
        )}

        {mode.value === EnumModes.occ ? (
          <div class={style.rankList}>
            <div class={style.title}>道路通行车次排行</div>
            <ul class={style.list}>
              {getRenderListData(areaInfoByDate.value).map((item, index) => (
                <li key={index} class={index < 5 && style.topOcc} onClick={() => handleClick(item)}>
                  <span class={style.index}>{index + 1}</span>
                  <span class={style.name}>{item.road_name}</span>
                  <span class={style.count}>{item.pass_veh_occ}</span>
                </li>
              ))}
            </ul>
          </div>
        ) : (
          <div class={style.rankList}>
            <div class={style.title}>道路平均车速排行</div>
            <ul class={style.list}>
              {getRenderListData(areaInfoByDate.value).map((item, index) => (
                <li key={index} class={index < 5 && style.topSpeed} onClick={() => handleClick(item)}>
                  <span class={style.index}>{index + 1}</span>
                  <span class={style.name}>{item.road_name}</span>
                  <span class={style.count}>{item.mean_velocity}</span>
                </li>
              ))}
            </ul>
          </div>
        )}

        <div class={style.chartContainer}>
          <div class={style.title}>{mode.value === "speed" ? "道路通行车次趋势" : "道路通行车次趋势"}</div>
          <div ref={chart} class={style.chart}></div>
        </div>
      </div>
    );
  },
});
