import request from "~/utils/request";
import {
    AiScoreData,
    Comment,
    Lianxi,
    RefResourceTypes,
    ScoreFroms,
    ScoreRefTypes,
    ScoreShifan,
    TaskFrom, TaskStatuses,
    TaskTypes
} from "~/types";
import {reactive} from "vue";
import useCourseCategory from "~/store/qumu-category";
import useTask from "~/store/task";

const store = reactive<{ queue: { [key: string]: number } }>({
    queue: {}
})

export default function useAi() {

    const {getTaskStatus, createTask, isTaskFinished} = useTask()

    async function compare(lianxi_url: string, scoreData: AiScoreData): Promise<any> {
        console.log("compare...", lianxi_url, scoreData)
        if (!scoreData.audio_type) {
            const {store, query} = useCourseCategory()
            if (!store.list.length) {
                await query()
            }
            scoreData.audio_type = store.list.find(x => x.is_default)?.category_key as string
        }

        return await createTask({task_type: TaskTypes.AI_SCORE, payload: scoreData});
    }

    async function check_score_status(refer: Lianxi | Comment) {
        if (refer.scores?.length) {
            for (let i = 0; i < refer.scores.length; i++) {
                let score = refer.scores[i];
                let {tasks} = score;
                if (tasks?.vals?.length) {
                    for (let j = 0; j < tasks?.vals.length; j++) {
                        let task = tasks?.vals[j];
                        if ([TaskTypes.AI_SCORE, TaskTypes.AUDIO_FILE_AI_SCORE].includes(task?.task_type) && task.task_from === TaskFrom.TaskServer && !isTaskFinished(task.task_status)) {
                            let status = await getTaskStatus(task?.task_id as string);
                            if (isTaskFinished(status))  {
                                refer.scores = await get_scores(refer.id as string);
                                // update score task status
                                let updateScore = (refer.scores || []).find(s => s.id === score.id);
                                if (updateScore) {
                                    let t = updateScore.tasks?.vals.find(t => t.task_id === task?.task_id)
                                    if (t) {
                                        t.task_status = status
                                        await request({
                                            url: "/api/v1/ws/update_score",
                                            data: {...updateScore}, method: "POST"
                                        })
                                    }
                                }
                                return true;
                            }
                        }
                    }
                }
            }
        }
    }

    async function score_lianxi(lianxi: Lianxi, shifan: ScoreShifan) {
        let lianxi_url = lianxi.ref_resources.find(r => r.resource_type === RefResourceTypes.Video)?.resource_url
        if (!lianxi_url) {
            lianxi_url = lianxi.ref_resources.find(r => r.resource_type === RefResourceTypes.Audio)?.resource_url
        }
        if (!lianxi_url) return;
        let task_id = await score_work(lianxi_url, shifan, lianxi.id, ScoreRefTypes.Lianxi);
        if (task_id) {
            lianxi.scores = await get_scores(lianxi.id) || [];
        }
    }

    async function score_work(work_url: string, shifan: ScoreShifan, ref_id: string, ref_type: ScoreRefTypes) {
        work_url = work_url.trim();
        let retried = store.queue[work_url] || 0;
        let {shifan_url, audio_type} = shifan
        try {
            // ai score
            let data: AiScoreData = {
                audio_type, reference_url: shifan_url,
                compare_url: work_url,
                score_from: ScoreFroms.MachineLearning,
                ref_type, ref_id
            }
            return await compare(work_url, data);
        } catch (e) {
            store.queue[work_url] = retried++;
            console.error("ai score failed...", e);
        }
    }

    async function score_comment(comment: Comment, shifan: ScoreShifan) {

        let video = comment.ref_resources?.find(x => x.resource_type === RefResourceTypes.Video);
        if (video?.resource_url) {
            let task_id = await score_work(video.resource_url, shifan, comment.id as string, ScoreRefTypes.Comment)
            if (task_id) {
                comment.scores = await get_scores(comment.id as string) || [];
            }
        }
    }

    async function get_scores(ref_id: string) {
        console.log('get score ref_id...', ref_id)
        const {r, d, e} = await request({url: '/api/v1/ws/find_scores_by_ref_id/' + ref_id, method: 'GET'});
        if (r) {
            return d;
        }
    }

    return {score_lianxi, score_comment, get_scores, check_score_status}

}
