<template>
    <view>
        <z-paging ref="paging" v-model="list" @query="handleQuery">
            <template #top>
                <mx-nav-bar v-bind="navBinding"/>
            </template>
            <ai-form-filter @force="init=false,$refs.paging.reload()"/>
            <ai-form-filter-shortcut/>
            <view class="p-20 fx-col gap-20">
                <voluntary-major v-for="item in list" :data="item"/>
            </view>
            <template #bottom>
                <ai-form-footer :total="total" @preview="handlePreview"/>
            </template>
            <uv-loading-page :loading="loading"/>
        </z-paging>
        <ai-form-cart ref="cartRef"/>
    </view>
</template>

<script>
import _ from 'lodash';
import LargeHeader from "@/pages/ie/components/large-header.vue";
import AiFormFooter from "@/pages/ie/entry-ai-form/components/ai-form-footer.vue";
import AiFormFilter from "@/pages/ie/entry-ai-form/components/ai-form-filter.vue";
import AiFormFilterShortcut from "@/pages/ie/entry-ai-form/components/ai-form-filter-shortcut.vue";
import VoluntaryMajor from "../components/card/voluntary-major.vue";
import AiFormCart from "./components/ai-form-cart.vue";
import MxConst from "@/common/MxConst";
import {postAIResult, submitVoluntary} from "@/api/webApi/ie-voluntary";
import {sleep, toast} from "@/uni_modules/uv-ui-tools/libs/function";
import {confirmAsync} from "@/utils/uni-helper";
import {useTransfer} from "@/hooks/useTransfer";
import {useProvidePageScroll} from "@/hooks/usePageScrollInjection";
import {useProvideMajorTreeService} from "@/pages/ie/hooks/useMajorTreeInjection";

export default {
    components: {AiFormFilterShortcut, AiFormFilter, AiFormFooter, LargeHeader, VoluntaryMajor, AiFormCart},
    data() {
        return {
            init: false,
            loading: false,
            navBinding: {title: 'AI志愿', mode: 'light', fixed: false, leftClickBlock: this.checkFormBeforeQuit},
            filter: {
                majorTypes: [],
                enumPickType: MxConst.enum.ai.pickType.all.value,
                enumPickEmpty: null,
                hasClearing: null,
                keyword: '',
                level: [],
                type: [],
                natureTypeCN: [],
                location: [],
                star: [],
                bxType: []
            },
            filterShortcut: [],
            config: {
                collegeMin: 2,
                collegeLimit: 5,
                majorLimit: 4,
                // 提交时仅保留的university属性，减少传输量
                commitUPropsKeep: ['code'],
                // 变更条件时，需要清空志愿表的filter属性，这些条件会影响专业概率
                confirmChangeFilterKeys: ['majorTypes', 'enumPickType', 'enumPickEmpty', 'hasClearing']
            },
            list: [],
            total: 0,
            // 填报项 // 包含：填报的院校引用，院校的专业用selected属性标记已填报
            selected: [],
            commit: {
                year: '', // 缺省的话后台会补充
                name: '', // 志愿表名，缺省的话后台会补充
                voluntaryType: MxConst.enum.ai.voluntaryType.ai,
            },
            showCart: false
        }
    },
    setup() {
        const {prevData, transferTo} = useTransfer()
        const scrollTop = useProvidePageScroll()

        return {
            prevData,
            transferTo,
            scrollTop
        }
    },
    computed: {
        request() {
            return {
                ...this.prevData,
                filter: this.filter
            }
        }
    },
    watch: {
        filter: {
            deep: true,
            handler: function () {
                this.init = false
                this.$refs.paging.reload()
            }
        }
    },
    provide() {
        return {
            getPrevData: () => this.prevData,
            getFilter: () => this.filter,
            getShortcut: () => this.filterShortcut,
            getConfig: () => this.config,
            getCart: () => this.selected,
            getCommit: () => this.commit,
            handleCartAdd: this.handleCartAdd,
            handleCartRemove: this.handleCartRemove,
            handleCartClear: this.handleCartClear,
            handleCommit: this.handleCommit
        }
    },
    methods: {
        checkFormBeforeQuit() {
            if (!this.selected.length) return true
            return confirmAsync('您有未保存的志愿表，确认退出？')
        },
        syncRowsToSelected(rows) {
            if (!Array.isArray(rows)) return
            rows.forEach(u => {
                // created `selected` property here, can make it reactive.
                u.majorDetails.forEach(m => m.selected = false)
                const match = this.selected.find(i => i.university.code == u.university.code)
                if (match && match.majorDetails.length == u.majorDetails.length &&
                    match.majorDetails.every(m1 => u.majorDetails.some(m2 => m1.majorCode == m2.majorCode))) {
                    // fully match, then copy major's selected property, and replace ele in cart.
                    u.majorDetails.forEach(m => {
                        const mMatch = match.majorDetails.find(item => item.majorCode == m.majorCode)
                        m.selected = mMatch.selected
                    })
                    const replaceIdx = this.selected.indexOf(match)
                    this.selected.splice(replaceIdx, 1, u)
                } else if (match) {
                    throw new Error('query list not match with selected elements')
                }
            })
        },
        async handleQuery(pageNum, pageSize) {
            const params = {
                pageNum, pageSize,
                ...this.request
            }
            console.log('handle query', params)
            try {
                if (pageNum == 1 && !this.init) this.loading = true
                const res = await postAIResult(params)
                this.syncRowsToSelected(res.rows)
                this.$refs.paging.completeByTotal(res.rows, res.total)
                this.total = res.total
                this.loading = false
            } catch (e) {
                console.log('ai request failed', e)
                this.loading = false
            } finally {
                this.init = true
            }
        },
        handleCartAdd(uElement, mElement) {
            const uAddDisable = !this.selected.includes(uElement) && this.selected.length >= this.config.collegeLimit
            if (uAddDisable) {
                toast(`最多填报${this.config.collegeLimit}个院校`)
                return
            }
            const mAllSelected = uElement.majorDetails.filter(i => i.selected)
            const mAddDisable = !mAllSelected.includes(mElement) && mAllSelected.length >= this.config.majorLimit
            if (mAddDisable) {
                toast(`每个院校最多填报${this.config.majorLimit}个专业`)
                return
            }
            if (!this.selected.includes(uElement)) this.selected.push(uElement)
            mElement.selected = true
        },
        handleCartRemove(uElement, mElement) {
            if (!mElement) {
                // remove all
                uElement.majorDetails.forEach(m => m.selected = false)
                _.remove(this.selected, uElement)
                return
            }
            // remove indicate
            mElement.selected = false
            const anySelected = uElement.majorDetails.some(i => i.selected)
            if (!anySelected) _.pull(this.selected, uElement)
        },
        handleCartClear() {
            this.selected.forEach(u => u.majorDetails.forEach(m => m.selected = false))
            _.remove(this.selected)
        },
        handlePreview() {
            if (!this.selected.length) {
                toast('请先至少选择1个专业到志愿表')
                return
            }
            this.$refs.cartRef.open()
        },
        async _validateCommit() {
            if (this.config.collegeMin && this.selected.length < this.config.collegeMin) {
                const err = `请至少填报${this.config.collegeMin}个院校`
                toast(err)
                return Promise.reject(err)
            }
        },
        async _createCommitData() {
            const uPropsKeep = this.config.commitUPropsKeep || []
            const uPropsClear = (u) => {
                const result = {}
                uPropsKeep.forEach(prop => result[prop] = u[prop])
                return result
            }
            const pureSelected = this.selected.map(u => ({
                ...u,
                university: uPropsClear(u.university),
                majorDetails: u.majorDetails.filter(m => m.selected)
            }))
            return {
                ...this.commit,
                request: this.request,
                details: pureSelected
            }
        },
        async handleCommit() {
            await this._validateCommit()
            const data = await this._createCommitData()
            const res = await submitVoluntary(data)
            toast('保存成功')
            await sleep(2000)
            const url = '/pages/ie/entry-ai-detail/entry-ai-detail'
            this.transferTo({url, params: {id: res.data, type: data.voluntaryType}, type: 'redirect'})
        }
    }
}
</script>

<style lang="scss" scoped>
::v-deep .zp-page-bottom-container {
    z-index: 10;
}
</style>
