<!--
 * 随机数相关
  -->
<script setup lang="ts">
import { onMounted, ref, reactive, nextTick, onBeforeUnmount } from 'vue';
import { getRandomInt } from 'src/common/utils';

// echarts
import * as echarts from 'echarts/core';
import {
  GridComponent,
  GridComponentOption,
  LegendComponent,
  LegendComponentOption,
} from 'echarts/components';
import { BarChart, BarSeriesOption } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([GridComponent, LegendComponent, BarChart, CanvasRenderer]);
type EChartsOption = echarts.ComposeOption<
  GridComponentOption | LegendComponentOption | BarSeriesOption
>;

const min = ref(10);
const max = ref(21);
const nowVal = ref(0);
const timer = ref<number | null>(null);
const refCharts = ref<HTMLElement | null>(null);

const state = reactive({
  randomMap: new Map(),
  chartDom: null as HTMLElement | null,
  myChart: null as any,
  option: null as EChartsOption | null,
  yAxisData: [] as string[],
  seriesData: [] as number[],
  divisionData: {
    int: 0,
    yu: 0,
  },
});
const randomList = reactive({
  value: [{ label: 0, value: 0, times: 0, divisionData: { int: 0, yu: 0 } }],
});

onMounted(() => {
  initDom();
  getOption();
  startDraw();
});

onBeforeUnmount(() => {
  console.log('onBeforeUnmount');
});

function onGetRandomInt() {
  const val = getRandomInt(min.value, max.value);
  nowVal.value = val;
  const getDivision = division(val, 5);
  state.divisionData.int = getDivision.int;
  state.divisionData.yu = getDivision.yu;

  if (state.randomMap.has(val)) {
    let currentNum = state.randomMap.get(val);
    state.randomMap.set(val, currentNum + 1);
  } else {
    state.randomMap.set(val, 1);
  }

  let sum = 0;
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  for (const [key, value] of state.randomMap) {
    sum += value;
  }

  let arr = [] as any[];
  for (const [key, value] of state.randomMap) {
    let item = {} as any;
    const itemGetDivision = division(value, 5);
    item.label = key;
    item.times = value; // 次数
    item.value = Number(((value / sum) * 100).toFixed(2)); // 百分比值
    item.divisionData = {};
    item.divisionData.int = itemGetDivision.int;
    item.divisionData.yu = itemGetDivision.yu;
    arr.push(item);
  }
  arr.sort((a: any, b: any) => {
    return Number(b.times) - Number(a.times);
  });

  let yAxisDataArr = [] as string[];
  let seriesData = [] as number[];
  arr.map((item: any) => {
    yAxisDataArr.push(String(item.label));
    seriesData.push(item.times);
  });
  state.yAxisData = yAxisDataArr;
  state.seriesData = seriesData;
  nextTick(() => {
    getOption();
    startDraw();
    randomList.value = arr;
  });

  if (timer.value) {
    onClearTimeout();
  }
  timer.value = window.setTimeout(() => {
    onGetRandomInt();
  }, 2000);
}

function onReset() {
  onClearTimeout();
  randomList.value = [];
  state.randomMap = new Map();
  state.yAxisData = [];
  state.seriesData = [];
  nowVal.value = 0;
  state.divisionData.int = 0;
  state.divisionData.yu = 0;
  getOption();
  startDraw();
}

function onClearTimeout() {
  if (timer.value) {
    window.clearTimeout(timer.value);
    timer.value = null;
  }
}

function initDom() {
  state.chartDom = refCharts.value as HTMLElement;
  state.myChart = echarts.init(state.chartDom);
}

function getOption() {
  state.option = {
    grid: {
      top: 50,
      bottom: 50,
      left: 50,
      right: 50,
    },
    xAxis: {
      max: 'dataMax',
    },
    yAxis: {
      type: 'category',
      data: state.yAxisData,
      inverse: true,
      animationDuration: 300,
      animationDurationUpdate: 300,
      //   max: 2, // only the largest 3 bars will be displayed
    },
    series: [
      {
        realtimeSort: true,
        type: 'bar',
        data: state.seriesData,
        label: {
          show: true,
          position: 'right',
          formatter: (val) => {
            return val.value + '次';
          },
          valueAnimation: true,
        },
        itemStyle: {
          color: '#78c0a8',
        },
        barWidth: 30,
      },
    ],
    legend: {
      show: false,
    },
    animationDuration: 0,
    animationDurationUpdate: 2000,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear',
  };
}

function startDraw() {
  state.option && state.myChart.setOption(state.option);
}

// 取整 取余
function division(n: number, m: number) {
  const yu = n % m;
  const int = parseInt(String(n / m));
  return {
    yu,
    int,
  };
}
</script>
<template>
  <div class="sty-array-out-of-order">
    <div class="btns">
      <q-btn
        :label="`获取随机整数：${min}~${max}`"
        color="primary"
        @click="onGetRandomInt"
      ></q-btn>
      <q-btn label="重置" color="primary" @click="onReset"></q-btn>
      <q-btn label="暂停" color="primary" @click="onClearTimeout"></q-btn>
      <q-badge outline color="primary"> {{ nowVal }} </q-badge>
    </div>

    <div class="content">
      <div class="sty-slider">
        <div class="slider-item" v-for="i in randomList.value" :key="i.label">
          <div class="sty-chip">
            <q-chip square color="primary" text-color="white">
              {{ i.label }}
            </q-chip>
          </div>
          <q-linear-progress
            size="25px"
            :value="i.value / 100"
            rounded
            color="primary"
          >
            <div class="absolute-full flex flex-center">
              <q-badge
                color="white"
                text-color="primary"
                :label="i.value + '%'"
              />
            </div>
          </q-linear-progress>
        </div>
        <q-separator />
        <div class="steping">
          <div class="step-item" v-for="i in randomList.value" :key="i.label">
            <div>
              <q-chip square color="primary" text-color="white">
                {{ i.label }}
              </q-chip>
            </div>
            <div class="zheng-item">
              <div
                class="zheng-box step5"
                v-for="m in i.divisionData.int"
                :key="m"
              ></div>
              <div class="zheng-box" :class="`step${i.divisionData.yu}`"></div>
            </div>
          </div>
        </div>
        <!-- <div class="text">
          <div
            class="zheng-box step5"
            v-for="i in state.divisionData.int"
            :key="i"
          ></div>
          <div class="zheng-box" :class="`step${state.divisionData.yu}`"></div>
        </div> -->
      </div>
      <div class="sty-chart"><div ref="refCharts" class="mychart"></div></div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.sty-array-out-of-order {
  .btns {
    > button {
      margin-right: $padding-md;
    }
  }
  .content {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }
  .sty-slider {
    margin-top: $padding-xl;
  }
  .slider-item {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
    margin-bottom: $padding-lg;
    .sty-chip {
      margin-right: $padding-md;
    }
  }
  .sty-chart {
    .mychart {
      width: 100%;
      height: 650px;
    }
  }
}

.steping {
  // border: 1px solid red;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: flex-start;
}
.step-item {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
}

.zheng-item {
  .zheng-box {
    width: 25px;
    height: 25px;
    position: relative;
    background-size: 100% 100%;
    margin-bottom: 10px;
  }
  .step1 {
    background-image: url('./icons/zheng-1.svg');
  }
  .step2 {
    background-image: url('./icons/zheng-2.svg');
  }
  .step3 {
    background-image: url('./icons/zheng-3.svg');
  }
  .step4 {
    background-image: url('./icons/zheng-4.svg');
  }
  .step5 {
    background-image: url('./icons/zheng-5.svg');
  }
}
</style>
