<template>
  <div>导出中……</div>
</template>

<script setup lang="ts">
  import { onMounted, ref } from 'vue';
  import { useRoute } from 'vue-router';

  import { UserState } from '@/store/modules/user/types';
  import { TrackConfigType } from '@/store/modules/app/types';
  import { useUserStore, useAppStore } from '@/store';
  import useTimeout from '@/hooks/timout';
  import { usePQueue } from '@/hooks/p-queue';
  import useDraw from './useDraw';

  import { TrackTaskData } from '../../../../electron/db/models/trackTask';
  import { TrackTaskDetailData } from '../../../../electron/db/models/trackTaskDetail';

  defineOptions({
    name: 'TrackTaskExport',
  });

  const route = useRoute();
  const TASK_KEY = 'task';

  const winId = Number(route.query.winId);
  const userInfo = JSON.parse(
    decodeURIComponent(window.atob(route.query.user as string))
  ) as UserState;
  const userStore = useUserStore();
  userStore.setInfo(userInfo);
  const appStore = useAppStore();

  const { addSetTimeout, clearSetTimeout } = useTimeout();

  const stop = ref(false);
  const task = ref({} as TrackTaskData);
  const trackConfig = ref({} as TrackConfigType);
  const queueConcurrency = 4;
  const groupCount = 10;

  function addLog(content: string, type?: 'info' | 'error') {
    window.api.logger(`win:${winId} ${content}`, type);
  }

  async function startGroupTask() {
    clearSetTimeout(TASK_KEY);
    if (stop.value) {
      stopTask();
      return;
    }

    const res = await window.db
      .getUnfinishTrackTaskDetails(task.value.id, groupCount)
      .catch((e) => {
        addLog(`00-获取任务失败：${e.message}`, 'error');
      });

    if (!res || !res.length) {
      addLog(`00-无任务`);
      addSetTimeout(TASK_KEY, startGroupTask, 1 * 1000);
      return;
    }

    await runGroupTask(res).catch(() => {});

    addSetTimeout(TASK_KEY, startGroupTask, 0);
  }

  async function runGroupTask(datas: TrackTaskDetailData[]) {
    const { buildQueue, stopQueue } = usePQueue({
      concurrency: queueConcurrency,
    });

    const runItemTask = async (itemTask: TrackTaskDetailData) => {
      const { runTask } = useDraw({
        domain: appStore.domain,
        task: task.value,
        taskDetail: itemTask,
        trackConfig: trackConfig.value,
        winId,
      });

      await runTask().catch(() => {});

      if (stop.value) {
        stopQueue();
        addLog(`00-任务终止`);
      }
    };

    const fetchFuncs = datas.map((item) => {
      return () => runItemTask(item);
    });
    await buildQueue(fetchFuncs);

    // 队列中存在未及时更新任务状态的数据
    await window.db.releaseAllRunningTaskDetailByIds(
      datas.map((item) => item.id)
    );
  }

  function stopTask() {
    addLog(`99-结束进程`);
    window.electron.closeProcessWindow(winId);
  }

  function registEvent() {
    window.electron.onStopRunning(() => {
      stop.value = true;
    });
  }

  async function initTask() {
    const domain = await window.db.getDict('domain');
    appStore.setInfo({ domain });

    addLog(`00-开启进程`);
    registEvent();

    const res = await window.db
      .getUnfinishTrackTask(userStore.curSchoolInfo.id)
      .catch(() => {
        addLog(`00-获取任务错误`, 'error');
      });
    if (!res) return;

    task.value = res;
    trackConfig.value = JSON.parse(res.trackConfig) as TrackConfigType;

    startGroupTask();
  }

  onMounted(() => {
    initTask();
  });
</script>
