import {createEventHook, injectLocal, provideLocal} from "@vueuse/core";
import {sleep} from "@/uni_modules/uv-ui-tools/libs/function";
import {empty} from "@/uni_modules/uv-ui-tools/libs/function/test";
import {recommendMajorSortFn} from "@/utils/common";
import {saveZhiyuan} from "@/api/modules/vhs";

const key = Symbol('VOLUNTARY_ASSISTANT')
export const useProvideVoluntaryAssistant = function (stepSvc, dataSvc, formSvc, cartSvc, highlightSvc) {

    const {title, currentStep} = stepSvc
    const {id, name, locking, selectedList, resetCart} = cartSvc
    const {voluntaryData} = dataSvc
    const {batch, model, mode, batchesList} = formSvc
    const {formedMajors, resetHighlight} = highlightSvc
    const beforeBack = createEventHook()
    const afterBack = createEventHook()
    const beforeForward = createEventHook()
    const afterForward = createEventHook()
    const complete = createEventHook()

    const handleBack = async function () {
        if (currentStep.value == 0) return
        await beforeBack.trigger()
        currentStep.value -= 1
        await afterBack.trigger()
    }

    const handleForward = async function () {
        if (currentStep.value == 2) return
        await beforeForward.trigger()
        currentStep.value += 1
        await afterForward.trigger()
    }

    const navBinding = computed(() => ({
        title: title.value,
        subTitle: name.value,
        leftIcon: currentStep.value > 0 ? 'arrow-left' : '',
        onLeftClick: handleBack
    }))

    const voluntaryDataCalculate = computed(() => {
        // NOTE: will override by history voluntary data in edit mode
        const param = toValue(voluntaryData) || {}
        const {batch: batchId} = toValue(batch)
        const defaultLimit = {groups: 9999, profession: 9999}
        // noinspection JSUnresolvedVariable
        const firedLimit = param.batches?.find(i => i.batch == batchId) || defaultLimit
        return {
            ...param,
            firedLimit
        }
    })

    const calculateScoreBatchRange = computed(() => {
        // for re-use
        const vData = toValue(voluntaryData)
        const vBatch = toValue(batch)
        if (empty(vData) || vBatch.batch) return [0, 0]
        const maxScore = vData.maxScore
        const minBatch = vBatch.score2 || vBatch.score1
        let maxBatch = maxScore
        const batchIndex = batchesList.value.indexOf(this.batch)
        if (batchIndex > 0) {
            const upBatch = batchesList.value[batchIndex - 1]
            maxBatch = upBatch.score2 || upBatch.score1
        }
        return [minBatch, Math.min(maxScore, maxBatch)]
    })

    const save = async (isMockHeader) => {
        if (toValue(id) && !toValue(name)) {
            uni.$ie.showError('请设置志愿表名称')
            return Promise.reject(false)
        }
        const wishes = selectedList.value.map(item => ({
            uniqueCode: item.uniqueCode,
            universityId: item.university.id,
            collegeCode: item.recruitPlan.collegeCode,
            code: item.university.code,
            jCode: item.jCode,
            name: item.university.name,
            pickType: item.pickType,
            enrollRatio: item.enrollRatio,
            enrollRatioText: item.enrollRatioText,
            ranking: item.university.ranking,
            rankingOfEdu: item.university.rankingOfEdu,
            seat: item.history?.seat,
            marjors: item.majors
                .filter(major => major.selected)
                .sort(recommendMajorSortFn)
                .map(major => ({
                    id: major.id,
                    code: major.marjorBelongs,
                    name: major.marjorName,
                    pickType: item.pickType,
                    submitMajorId: major.history?.id,
                    enrollRatio: major.enrollRatio,
                    enrollRatioText: major.enrollRatioText,
                    enrollFluctuate: major.enrollFluctuate
                }))
        }))
        if (wishes.length < 1) {
            // NOTE: 职高对口院校较少，降低填报限制
            uni.$ie.showError('至少选择1个志愿组')
            return Promise.reject(false)
        }
        locking.value = true
        uni.$ie.showLoading()
        const vBatch = toValue(batch)
        const vModel = toValue(model)
        const vMode = toValue(mode)
        const data = {
            batch: vBatch.batch,
            detail: {
                batch: {
                    batch: vBatch.batch,
                    name: vBatch.name,
                    score1: vBatch.score1 || '',
                    score2: vBatch.score2 || '',
                    scoreBatchLimit: calculateScoreBatchRange.value[1],
                    recommand: true,
                    scores: [],
                    wishes: wishes,
                    sort: voluntaryDataCalculate.value.sort,
                    paramBatches: [voluntaryDataCalculate.value.firedLimit],
                    highlightMajorIds: Object.keys(formedMajors.value)
                },
                mode: vMode,
                score: vModel.score,
                seatInput: vModel.seatInput,
                year: vBatch.year,
                isMock: isMockHeader
            },
            id: id.value,
            name: name.value
        }
        let res = null
        try {
            res = await saveZhiyuan(data)
            uni.$ie.showToast('保存成功，即将跳转3')
            await sleep(1000)
            uni.$ie.showToast('保存成功，即将跳转2')
            await sleep(1000)
            uni.$ie.showToast('保存成功，即将跳转1')
            await sleep(500)
            await complete.trigger(res.data)
        } finally {
            locking.value = false
            uni.hideLoading()
        }
    }

    const resetAll = () => {
        resetCart()
        resetHighlight()
    }

    const options = {
        navBinding,
        handleBack,
        handleForward,
        voluntaryDataCalculate,
        save,
        resetAll,
        onBeforeBack: beforeBack.on,
        onAfterBack: afterBack.on,
        onBeforeForward: beforeForward.on,
        onAfterForward: afterForward.on,
        onComplete: complete.on
    }
    provideLocal(key, options)
    return options
}

export const useInjectVoluntaryAssistant = function (useDefaultVal) {
    return injectLocal(key, useDefaultVal ? {voluntaryDataCalculate: {}} : undefined)
}