import { ref } from 'vue';
import { trackExportDetailListPage, trackExportListPage } from '@/api/task';
import {
  TrackExportDetailItem,
  TrackExportDetailListFilter,
  TrackExportDetailListParams,
  TrackExportItem,
  TrackExportListFilter,
  TrackExportListPageRes,
} from '@/api/types/task';
import { usePQueue } from '@/hooks/p-queue';
import {
  TRACK_TASK_DETAIL_STATUS,
  TRACK_TASK_STATUS,
} from '../../../../electron/db/enumerate';
import { TrackTaskCreationAttributes } from '../../../../electron/db/models/trackTask';

export default function useTask() {
  const pageSize = 20;
  const trackTaskId = ref(0);

  async function createTrackTask(data: TrackTaskCreationAttributes) {
    const res = await window.db.createTrackTask(
      { ...data, status: TRACK_TASK_STATUS.INIT },
      []
    );
    trackTaskId.value = res.id;
  }
  async function updateTrackTaskReady() {
    await window.db.updateTrackTaskStatus({
      id: trackTaskId.value,
      status: 'READY',
    });
  }

  async function getTrackExportList(params: TrackExportListFilter) {
    const trackExportList: TrackExportItem[] = [];
    const res = await trackExportListPage({
      ...params,
      pageNumber: 1,
      pageSize,
    });
    trackExportList.push(...res.records);

    if (res.pages > 1) {
      const fetchFuncs = [];
      for (let i = 2; i <= res.pages; i++) {
        fetchFuncs.push(() =>
          trackExportListPage({
            ...params,
            pageNumber: i,
            pageSize,
          })
        );
      }

      const { buildQueue } = usePQueue({ concurrency: 6 });
      const fetchResult = await buildQueue<TrackExportListPageRes>(fetchFuncs);
      fetchResult.forEach((item) => {
        trackExportList.push(...item.records);
      });
    }

    // get details
    const detailFetchFuncs = trackExportList.map((item) => {
      return () =>
        getTrackExportDetailList({
          examId: item.examId,
          paperNumber: item.paperNumber,
        });
    });
    const { buildQueue } = usePQueue({ concurrency: 1 });
    await buildQueue(detailFetchFuncs);
  }

  interface CreateTrackTaskDetailsResult {
    total: number;
    pages: number;
    pageNumber: number;
  }

  async function getTrackExportDetailList(params: TrackExportDetailListFilter) {
    const filterData = {
      ...params,
      pageSize,
    };
    const res = await createTrackTaskDetails({
      ...filterData,
      pageNumber: 1,
    });

    if (res.pages <= 1) return;

    const fetchFuncs = [];
    for (let i = 2; i <= res.pages; i++) {
      fetchFuncs.push(() =>
        createTrackTaskDetails({
          ...filterData,
          pageNumber: i,
        })
      );
    }

    const { buildQueue } = usePQueue({ concurrency: 6 });
    await buildQueue<CreateTrackTaskDetailsResult>(fetchFuncs);
  }

  async function createTrackTaskDetails(params: TrackExportDetailListParams) {
    const res = await trackExportDetailListPage(params);
    const details = res.records
      .filter((item) => item.sheetUrls)
      .map((item) => {
        return {
          trackTaskId: trackTaskId.value,
          studentId: item.studentId,
          studentName: item.studentName,
          studentCode: item.studentCode,
          className: item.teachClassName || item.className,
          status: TRACK_TASK_DETAIL_STATUS.INIT,
        };
      });
    await window.db.createTrackTaskDetails(details);

    return {
      total: res.total,
      pages: res.pages,
      pageNumber: params.pageNumber,
    };
  }

  async function createTrackTaskDetailsFromStudents(
    datas: TrackExportDetailItem[]
  ) {
    const details = datas
      .filter((item) => item.sheetUrls)
      .map((item) => {
        return {
          trackTaskId: trackTaskId.value,
          studentId: item.studentId,
          studentName: item.studentName,
          studentCode: item.studentCode,
          className: item.teachClassName || item.className,
          status: TRACK_TASK_DETAIL_STATUS.INIT,
        };
      });
    await window.db.createTrackTaskDetails(details);
  }

  return {
    trackTaskId,
    createTrackTask,
    updateTrackTaskReady,
    getTrackExportList,
    getTrackExportDetailList,
    createTrackTaskDetailsFromStudents,
  };
}
