import {reactive} from "vue";
import {
    Comment,
    CommonTask,
    Daka,
    Jihua,
    MultiVals, RefResource,
    RefResourceTypes,
    ResourceNoteGroup,
    ScoreShifan,
    TaskFrom
} from "~/types";
import useTask from "~/store/task";
import usePool from "~/store/pool";

const store = reactive<{
    timer: number, getter?: () => Daka | Jihua, dangerous?: string, counter: number
}>({
    timer: 0,
    counter: 0
})

export default function useTimer() {

    const {isTaskFinished} = useTask()
    const {getKey, remove} = usePool()

    const task_valid = (task: CommonTask) => task && task.task_id && task.task_id !== "placeholder-task" && task.task_from !== TaskFrom.AI

    const has_pending_tasks = ({tasks}: { tasks?: MultiVals<CommonTask> }) => tasks?.vals?.some(t => task_valid(t) && !isTaskFinished(t.task_status))

    function comments_pending ({comments}: {comments?: Comment[]}, shifan?: ScoreShifan) {
        return comments?.some(({ref_resources, scores, resource_note_group}) => {
            // check resource
            if (ref_resources?.some(has_pending_tasks)) return true;
            // check resource note group
            if (rng_pending(resource_note_group)) return true;
            // check score
            let video = ref_resources?.find(r => r.resource_type === RefResourceTypes.Video);
            return !!(shifan && video && video.resource_url && !scores?.length);

        })
    };

    function rng_pending (rng?: ResourceNoteGroup, shifan?: ScoreShifan) {
        return rng?.resource_notes?.some(rn => comments_pending(rn, shifan))
    }

    const is_pending = () => {
        if (!store.getter || !store.getter()) return false;
        let {course_sections} = store.getter()
        let scoring_audio = getKey("scoring_audio");
        // check if we have any tasks need to refresh
        return course_sections.some(qs => {
            // 1. check course section tasks
            // 1.1 course section resource
            let ref_resources = qs.ref_resources || qs.resources;
            if (ref_resources?.some(has_pending_tasks)) return true;
            // 1.2 course section resource notes
            if (rng_pending(qs.resource_note_group)) return true;

            let shifan_url = ref_resources?.find(r => r.is_shifan)?.resource_url;
            let audio_type = qs.course_category_key;
            let score_shifan = shifan_url ? {shifan_url, audio_type} : undefined;
            // 2. check lianxi task
            return qs.lianxis?.some(lianxi => {
                // check cached_audio
                // @ts-ignore
                if (!lianxi.audio && scoring_audio && scoring_audio?.ref_id === lianxi.id) {
                    let audio = scoring_audio as RefResource;
                    lianxi.audio = audio;
                    lianxi.ref_resources.push(audio)
                }
                if (lianxi.ref_resources.some(has_pending_tasks)) return true;
                if (lianxi.scores?.some(has_pending_tasks)) return true;
                if (!lianxi.scores?.length && score_shifan) {
                    // if lianxi has no scores for now, but we have shifan and audio/video
                    // we think it's pending, since maybe the scores data haven't been saved or audio file still not converted, etc.
                    // for audio lianxi ,we'll even has no resource url at first since we need time to generate the mp3 file and url
                    if (lianxi.ref_resources.some(r => (r.resource_url && r.resource_type == RefResourceTypes.Video) || r.resource_type === RefResourceTypes.Audio)) {
                        if (!store.dangerous) {
                            store.dangerous = lianxi.id;
                        }
                        if (store.dangerous === lianxi.id) {
                            store.counter++
                        }
                        return true;
                    }
                }
                if (store.dangerous === lianxi.id) {
                    store.dangerous = undefined;
                    store.counter = 0;
                }
                // 3. check piyue
                return !!lianxi.piyues?.some(p => comments_pending(p, score_shifan) || rng_pending(p.resource_note_group, score_shifan));
            })
        });
    }

    const stopTimer = () => {
        clearInterval(store.timer);
        store.getter = undefined;
        store.dangerous = undefined;
        store.counter = 0;
    }

    const startTimer = (getter: () => Daka | Jihua, checker: () => void) => {
        stopTimer();
        store.getter = getter
        // run one time at least to make sure ref resource transform success
        checker();
        store.timer = window.setInterval(() => {
            let has_pending = is_pending();
            console.log("is pending...", has_pending, store.dangerous, store.counter)
            if (has_pending) {
                checker()
                //to avoid infinite timer, only support 10 times for dangerous case
                if (store.dangerous && store.counter >= 10) {
                    stopTimer();
                }
            } else {
                stopTimer()
            }
        }, 5000)
    }


    return {startTimer, stopTimer}
}
