import {createApp} from 'vue'
import {createRouter, createWebHistory} from "vue-router";
import routes from "~/routes";
// @ts-ignore
import wx from 'weixin-js-sdk';
import App from './App.vue'
import 'vant/lib/index.css'
import 'leaflet/dist/leaflet.css'
import '~/fontawesome/all.css';
import './index.less'
// @ts-ignore
import useUser from '~/store/user'
import useOrg from "~/store/org";
import cookie from "~/utils/cookie";
import {CurrentOrgId, CurrentUserRole, HtyAuthToken, HtySudoToken, HtyUnionIDToken, pad} from "~/utils";
import {HtyRoles, HtyStates, UserStates} from "~/types";
import useTimer from "~/store/timer";

const router = createRouter({
    history: createWebHistory(),
    routes
})

const weixin = {
    // @ts-ignore
    install: app => {
        // @ts-ignore
        app.config.globalProperties.$weixin = wx;
    }
}

// @ts-ignore
Date.prototype.toJSON = function () {
    let year = this.getFullYear(),
        month = this.getMonth() + 1,
        date = this.getDate(),
        hour = this.getHours(),
        minute = this.getMinutes(),
        second = this.getSeconds();
    return [year, pad(month), pad(date)].join('-') + 'T' + [pad(hour), pad(minute), pad(second)].join(':')
}

const parseCurrentOrgIdFromToken = (token: string | null): string | undefined => {
    if (!token) return undefined;
    try {
        const tokenParts = token.split('.');
        if (tokenParts.length < 2) return undefined;
        const payloadRaw = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');
        const payloadRawWithPadding = payloadRaw.padEnd(Math.ceil(payloadRaw.length / 4) * 4, '=');
        const payloadJson = decodeURIComponent(
            atob(payloadRawWithPadding)
                .split('')
                .map((char) => `%${(`00${char.charCodeAt(0).toString(16)}`).slice(-2)}`)
                .join('')
        );
        const payload = JSON.parse(payloadJson) as Record<string, unknown>;
        if (typeof payload.current_org_id === 'string' && payload.current_org_id) {
            return payload.current_org_id;
        }
        if (typeof payload.sub === 'string' && payload.sub.length > 0) {
            const subjectPayload = JSON.parse(payload.sub) as Record<string, unknown>;
            if (typeof subjectPayload.current_org_id === 'string' && subjectPayload.current_org_id) {
                return subjectPayload.current_org_id;
            }
        }
        return undefined;
    } catch (_error) {
        return undefined;
    }
};

router.beforeEach(async (to, from , next) => {
    document.title = to.meta.title as string;
    let { store, read, login, logout, chooseRole, getUnreadTongzhis, set_editing } = useUser();
    let { store: orgStore, loadMyOrgs, switchOrg } = useOrg();
    set_editing(false)
    store.unionid = (store.unionid || cookie.get(HtyUnionIDToken) || '').toString();
    if (!store.current.hty_id) {
        if (window.localStorage.getItem(HtyAuthToken) && window.localStorage.getItem(HtySudoToken)) {
            await read();
        } else {
            window.localStorage.removeItem(HtyAuthToken);
            window.localStorage.removeItem(HtySudoToken);
            let userStatus = Number(to.query.status || UserStates.Anonymous);

            if (userStatus === UserStates.Registered) {
                // 已注册，登录获取用户信息
                let new_unionid = to.query.unionid;
                if(!store.unionid || (new_unionid && new_unionid !== store.unionid)) {
                    if(new_unionid) {
                        cookie.set(HtyUnionIDToken, new_unionid);
                        await login(new_unionid.toString())
                    }
                } else {
                    await login(store.unionid)
                }
            } else {
                if (to.path !== '/' && !to.path.startsWith('/guest')) {
                    await router.replace('/')
                }
                next()
                return
            }
        }
    }
    // switched unionid（URL 与当前会话不一致时）
    if (to.query.unionid && store.unionid !== to.query.unionid) {
        const rawQ = to.query.unionid;
        const qUnionStr = String(Array.isArray(rawQ) ? rawQ[0] : rawQ || '');
        // 已登录且 URL 中的 unionid 与当前用户不同：多为带毒分享链接，剥离身份参数而非 logout
        if (store.current.hty_id && qUnionStr) {
            const cur = store.current as { union_id?: string };
            const currentUnion = String(
                cur.union_id != null && cur.union_id !== '' ? cur.union_id : store.unionid || ''
            );
            if (currentUnion && qUnionStr !== currentUnion) {
                const nextQuery = { ...to.query } as Record<string, string | string[] | undefined | null>;
                delete nextQuery.unionid;
                delete nextQuery.openid;
                delete nextQuery.status;
                await router.replace({ path: to.path, query: nextQuery });
                next();
                return;
            }
        }
        cookie.set(HtyUnionIDToken, qUnionStr);
        logout();
        await login(qUnionStr);
        next();
        return;
    }
    let {enabled, is_registered, roles, union_id} = store.current;
    console.log(enabled, is_registered, to.path);
    // 未启用、未注册 用户进入首页操作
    if ((!enabled || !is_registered) && to.path !== '/' && !to.path.startsWith('/guest')) {
        if (store.currentRole){
            delete store.currentRole
        }
        window.localStorage.removeItem(CurrentUserRole)
        await router.replace('/')
    } else {
        if (!store.currentRole) {
            let prev_role = window.localStorage.getItem(CurrentUserRole)
            // check if prev role is still valid
            if (prev_role && roles && roles.some(r => r.role_key === prev_role && r.role_status === HtyStates.ACTIVE)) {
                chooseRole(prev_role as HtyRoles)
            } else {
                window.localStorage.removeItem(CurrentUserRole);
                let activeRoles = roles?.filter(r => r.role_status === HtyStates.ACTIVE)
                if(activeRoles?.length === 1) {
                    chooseRole(activeRoles[0].role_key)
                } else if (to.path !== '/') {
                    await router.replace('/')
                }
            }
        } else if (enabled && is_registered) {
            getUnreadTongzhis();
        }
    }

    if (enabled && is_registered && to.path !== '/' && to.path !== '/org/select') {
        const authToken = window.localStorage.getItem(HtyAuthToken);
        const tokenOrgId = parseCurrentOrgIdFromToken(authToken);
        if (!tokenOrgId) {
            const organizations = await loadMyOrgs();
            if (organizations.length === 1) {
                const switched = await switchOrg(organizations[0].id);
                if (!switched) {
                    next(false);
                    return;
                }
                const currentAuthToken = window.localStorage.getItem(HtyAuthToken);
                if (currentAuthToken) {
                    window.localStorage.setItem(HtySudoToken, currentAuthToken);
                }
            } else if (organizations.length > 1) {
                await router.replace('/org/select');
                next();
                return;
            }
        } else if (!orgStore.currentOrgId) {
            window.localStorage.setItem(CurrentOrgId, tokenOrgId);
            orgStore.currentOrgId = tokenOrgId;
        }
    }

    let {stopTimer} = useTimer()
    stopTimer();
    if (to.path.endsWith("/profile") && store.currentRole && !to.path.includes(store.currentRole.toLowerCase())) {
        await router.replace("/" + store.currentRole.toLowerCase() + "/profile")
    }

    next();
})

createApp(App).use(router).use(weixin).mount('#app')

