import request from "../utils/request";
import {
    Comment,
    HtyRoles,
    NotedResources,
    NotifyParam,
    Piyue,
    RatingTexts,
    ResourceNote,
    ResourceNoteGroup,
    ResourceNoteTypes, ScoreShifan
} from "~/types";
import useLoading from "~/store/loading";
import useComment from "~/store/comment";
import {showFailToast} from "vant";
import useUser from "~/store/user";
import useNotify from "~/store/notify";


export default function usePiyue() {
    const {load_start, load_done} = useLoading()
    const {check_comments_task, prepare_comment} = useComment()
    const usingUser = useUser();
    const { notify_ws } = useNotify();

    const notify = (params: NotifyParam, role_key: HtyRoles) =>  notify_ws(params, role_key);

    async function add_resource_notes(notes: ResourceNote[], resources: NotedResources, ref_id: string, ref_type: string) {
        load_start()
        let data = await getRNG(notes, resources);
        data.ref_id = ref_id;
        data.ref_type = ref_type;
        data.created_by = usingUser.store.current.hty_id;
        const {r, d, e} = await request({url: '/api/v1/ws/create_or_update_resource_note_group', method: 'POST', data});
        load_done();
        if (r) {
            data.id = d;
            return data;
        }
        showFailToast(e);
    }

    async function update_resource_notes(notes: ResourceNote[], resources: NotedResources, origin: ResourceNoteGroup) {
        load_start()
        let data = await getRNG(notes, resources);
        let {ref_resource_ids, resource_note_ids, resource_notes, ...rest} = origin;
        data = {...data, ...rest}
        const {r, d, e} = await request({url: '/api/v1/ws/create_or_update_resource_note_group', method: 'POST', data});
        load_done();
        if (r) {
            return data;
        }
        showFailToast(e);
    }


    async function getRNG(notes: ResourceNote[], {qupu, video, audio}: NotedResources) {
        let user_id = usingUser.store.current.hty_id;
        let rng: ResourceNoteGroup = {
            ref_resource_ids: {
                vals: [
                    qupu?.hty_resource_id as string,
                    video?.hty_resource_id as string
                ].filter(x => !!x)
            },
            resource_notes: [],
            created_by: user_id
        }
        for(let i = 0; i < notes.length; i++)  {
            let {comment, comments, note_type, lat_pos, time_pos, resource_pos, ...rest} = notes[i];
            comments = comments || [];
            if (comment) {
                if (comment.id) {
                    let index = comments.findIndex(c => c.id === comment?.id);
                    comment.id = undefined;
                    comments[index] = await prepare_comment(comment);
                } else {
                    comments.push(await prepare_comment(comment))
                }
            }
            note_type = note_type || ResourceNoteTypes.Alphabet;
            if (note_type === ResourceNoteTypes.Alphabet) {
                // when update, resource_pos.vals already have value, skip
                if (!resource_pos?.vals.length) {
                    resource_pos = {vals: []};
                    resource_pos.vals.push({
                        hty_resource_id: qupu?.hty_resource_id,
                        ref_resource_id: qupu?.id,
                        lat_pos
                    })
                    if (video && time_pos) {
                        resource_pos.vals.push({
                            hty_resource_id: video?.hty_resource_id,
                            ref_resource_id: video?.id,
                            time_pos
                        })
                    }
                }
            } else{
                if (resource_pos?.vals.length) {
                    for (let j = resource_pos.vals.length - 1; j >= 0; j--) {
                        let pos = resource_pos.vals[j];
                        if (!pos.time_pos?.time && !pos?.multi_lat_pos?.points.vals.length) {
                            resource_pos?.vals.splice(j, 1);
                        } else {
                            pos.hty_resource_id = qupu?.hty_resource_id;
                            pos.ref_resource_id = qupu?.id;
                        }
                    }
                }
                if (!resource_pos?.vals.some(p => p.multi_lat_pos?.points.vals.length)) {
                    // skip if positions are absence
                    continue;
                }
            }
            rng.resource_notes?.push({...rest, comments, note_type, created_by: user_id, resource_pos})
        }
        return rng;
    }

    async function prepare_piyue({lianxi_id, rating, comments}: Piyue, notes: ResourceNote[], notedResources: NotedResources, answer?: Comment) {

        if (answer && answer.content && Object.keys(answer.content).length > 0) {
            comments.push(answer);
        }
        rating.comment = rating.comment || {};
        if (!rating.comment?.text) {
            rating.comment.text = RatingTexts[rating.stars];
        }

        let data: Piyue = {
            lianxi_id, rating, comments: [],
            resource_note_group: await getRNG(notes, notedResources)
        }

        for(let i = 0; i < comments.length; i++) {
            data.comments.push(await prepare_comment(comments[i]))
        }
        return data;
    }

    async function create_piyue(piyue: Piyue) {
        load_start()
        piyue.teacher_id = usingUser.store.current.hty_id;
        piyue.teacher_name = usingUser.store.current.real_name;
        const {r, d, e} = await request({
            url: '/api/v1/ws/create_piyue2', method: 'POST', data: piyue
        });
        load_done()
        if (!r) {
            if (e.startsWith("DuplicateErr")) {
                showFailToast({
                    message: "该练习已被批阅过！",
                    onClose() {
                        window.location.reload();
                    }
                })
            } else {
                showFailToast(e);
            }
        } else {
            return d;
        }
    }

    async function check_piyue_tasks(piyue: Piyue, shifan?: ScoreShifan) {
        if (piyue?.resource_note_group && piyue.resource_note_group.resource_notes?.length) {
            for (let k = 0; k < piyue.resource_note_group.resource_notes.length; k++) {
                let { id, comments } = piyue.resource_note_group.resource_notes[k];
                await check_comments_task(id as string, comments, shifan)
            }
        }
        await check_comments_task(piyue.id as string, piyue.comments, shifan);
    }

    return {
        add_resource_notes, check_piyue_tasks, create_piyue, prepare_piyue, notify, update_resource_notes, getRNG
    }
}
