import { defineStore } from 'pinia'
import {
    arrayDelete,
    arrayToTree,
    defineMenu,
    findMenuById,
    getAllId, getRouteByPath,
    menuIsShow,
    randomNum
} from "../router/router-util";
import {nextTick} from "vue";
import router from "@/router";
import {homeTab} from "@/router/home";
import {menuList} from '@/router/menu-list';
import mitt from "@/mitt";
import {useSettingStore} from "./setting";
import {useComStore} from "./com";


/**
 * 有关 app 临时布局的相关状态
 */
export const useAppStore = defineStore({
    id: 'app',
    state: () => {
        return {
            // ------------------------------- 菜单 -------------------------------
            menuList: [],       // 全部菜单集合
            showList: [],		// 显示的菜单集合（id集合）
            searchList: [],     // 搜索列表（菜单集合的平面展开）
            activeMenuId: '0',		// 正在高亮的菜单id

            // ------------------------------- tab -------------------------------
            homeTab: homeTab,	// 主页首屏 Tab
            nativeTab: homeTab,		// 当前正显示的Tab
            tabList: [homeTab],		// 当前 Tab 集合
            viewNameList: [homeTab.id],       // 受缓存的 tab-name 集合

            // ------------------------------- 状态 -------------------------------
            isOpen: true,			// 当前是否展开菜单 (整体框架)
            navCmbRightShow: true,  // 分栏布局的右侧子菜单，是否显示 
            isShowSetting: false,   // 是否显示全局设置界面
            isOsLoading: false,     // 是否显示全局 loading 图 
            osLoadingMsg: '',       // 全局 loading 的文字 
            isInit: false,          // 标记模板是否已经初始化完成
        }
    },
    actions: {

        // ------------------- 初始化相关 --------------------
        // 初始化模板, 此方法必须且只能调用一次
        init: function() {

            // 设置 icon
            const settingStore = useSettingStore();
            const iconDom = document.querySelector('.admin-icon');
            if(iconDom) {
                iconDom.setAttribute('href', settingStore.logo);
            }

            // 打印版本信息 
            var str = `${settingStore.title} ${settingStore.version} (${settingStore.updateTime})`;
            console.log('%c%s', 'color: green; font-size: 13px; font-weight: 700; margin-top: 2px; margin-bottom: 2px;', str);
            
            // 监听窗口变动函数 
            window.onresize = function (){
                useComStore().winResize();
            };
            
            // 手动触发一下窗口变动监听
            // window.onresize();

            // 标记模板已初始化完成 
            this.isInit = true;
        },
        // 初始化菜单：
        // 	showList = 显示菜单id数组  —— （注意是id的数组），你填哪些id哪些菜单才会显示 ，为空时代表显示所有
        initMenu: function(showList) {
            this.setMenuList(menuList, showList);
        },
        // 写入菜单:
        // 	menuList = 全部菜单  —— 可以是已经渲染好的 tree 数组，也可以是一个尚未渲染的一维数组（你只要指定好 parentId，Sa-Admin内部会自动渲染）
        // 	showList = 显示菜单id数组  —— （注意是id的数组），你填哪些id哪些菜单才会显示 ，为空时代表显示所有
        setMenuList: function(menuList, showList) {
            // 设置 全部菜单
            this.menuList = arrayToTree(menuList);
            // 设置 显示的菜单id
            showList = showList || getAllId(menuList);
            for (var i = 0; i < showList.length; i++) {
                showList[i] = showList[i] + '';
            }
            this.showList = showList;
            this.f5SearchList();
        },
        // 刷新待选列表
        f5SearchList: function() {
            var _searchList = [];

            let index = 1;
            function push(id, level, text) {
                _searchList.push({id: id, level: level, text: (index++) + ". " + text});
            }

            // 遍历菜单
            const children = this.menuList;
            for (let menu1 of children) {
                if(menuIsShow(menu1) === false) continue;
                if(menu1.children) {
                    for (let menu2 of menu1.children) {
                        if(menuIsShow(menu2) === false) continue;
                        if(menu2.children) {
                            for (let menu3 of menu2.children) {
                                if(menuIsShow(menu3) === false) continue;
                                if(menu3.children) {
                                    for (let menu4 of menu3.children) {
                                        if(menuIsShow(menu4) === false) continue;
                                        push(menu4.id, [menu1, menu2, menu3, menu4], menu1.title + ' > ' + menu2.title + ' > ' + menu3.title + ' > ' + menu4.title);
                                    }
                                } else {
                                    push(menu3.id, [menu1, menu2, menu3], menu1.title + ' > ' + menu2.title + ' > ' + menu3.title);
                                }
                            }
                        } else {
                            push(menu2.id, [menu1, menu2], menu1.title + ' > ' + menu2.title);
                        }
                    }
                } else {
                    push(menu1.id, [menu1], menu1.title);
                }
            }
            this.searchList = _searchList;
        },
        
        // 动态写入 logo、title、等信息 
        setAppInfo: function (appCfg) {
            // console.log(appCfg)
            if(appCfg.isDynamicInfo === 'true' || appCfg.isDynamicInfo === true) {
                let settingStore = useSettingStore();
                settingStore.logo = appCfg.appLogo ?? settingStore.logo;
                settingStore.title = appCfg.appName ?? settingStore.title;
                settingStore.version = appCfg.appVersion ?? settingStore.version;
                settingStore.updateTime = appCfg.appUpdateTime ?? settingStore.updateTime;
                settingStore.intro = appCfg.appIntro ?? settingStore.intro;
            }

        },
        // ------------------- Menu 相关操作 --------------------
        // 根据 id 查找 Menu
        getMenuById: function(id) {
            return findMenuById(this.menuList, id);
        },
        // 显示某个菜单，根据id
        showMenuById: function(id, param = '') {
            var menu = this.getMenuById(id);
            if(menu) {
                if(param) {
                    menu.path = "";
                }
                this.showTab(menu, param);
                return menu;
            }
        },
        // 显示homeTab
        showHome: function() {
            this.showTab(this.homeTab);
        },
        // 让左侧菜单自动关联高亮的 tab 
        relationActiveMenuId: function () {
            console.log('this.nativeTab.id ', this.nativeTab.id)
            this.activeMenuId = this.nativeTab.id + '';	// 左边自动关联, 如果左边没有，则无效果  
        },
        // ------------------- Tab 相关操作 --------------------
        // 刷新Tab
        f5Tab: function(tab) {
            // 如果是当前高亮 tab
            if(tab === this.nativeTab) {
                mitt.emit('f5CurrView');
            } else {
                // 如果不是
                arrayDelete(this.viewNameList, tab.name);
                nextTick(function (){
                    this.viewNameList.push(tab.name);
                }.bind(this));
            }
        },
        // 刷新当前 tab 卡片
        f5NativeTab: function (){
            this.f5Tab(this.nativeTab);
        },
        // 获取 Tab，根据 id
        getTabById: function(id) {
            for (var i = 0; i < this.tabList.length; i++) {
                if(this.tabList[i].id + '' === id + '') {
                    return this.tabList[i];
                }
            }
            return null;
        },
        // 添加一个Tab  {id,name,url}
        addTab: function(tab) {
            // 如果没有提供id，则随机一个
            if(!tab.id) {
                tab.id = new Date().getTime() + '' + randomNum();
            }
            // if(tab.isNeedLoad === undefined) {
            //     tab.isNeedLoad = true;
            //     // Vue.set(tab, 'isNeedLoad', true);
            // }

            this.tabList.push(tab);
            if(this.viewNameList.indexOf(tab.name) === -1) {
                this.viewNameList.push(tab.name);
            }
            // tab 超过 20 个，提示过多，如果用户无视继续添加则超过 30 个后不再提示
            // if(this.tabList.length > 20 && this.tabList.length < 30) {
            //     ElMessage({message: '选项卡过多会造成窗口卡顿，建议您关闭不使用的窗口', type: 'warning'});
            // }
        },
        // 显示某个页面  (如果不存在, 则先添加)
        showTab: function(tab, param) {
            // 标注：需要此刻加载
            // tab.isNeedLoad = true;
            // this.$set(tab, 'isNeedLoad', true);

            // 如果是外部链接
            if(tab.isBlank) {
                return open(tab.url);
            }
            // 如果是当前正在显示的tab , 则直接返回，无需继续操作
            if(tab === this.nativeTab) {
                return;
            }
            // 如果是内部连接
            // if(tab.url) {
            //     tab.path = "/iframe?url=" + encodeURIComponent(tab.url);
            // }
            // 如果是click函数
            if(tab.click) {
                if(tab.click() !== true) {
                    return;
                }
            }
            // 如果这个 tab 还没有添加到 tabList 上
            if(this.getTabById(tab.id) == null){
                this.addTab(tab);
            }
            // 然后开始显示这个 tab
            this.nativeTab = tab;
            // this.nativeTab.is_load = true;	// 标注：已经加载过了
            this.activeMenuId = tab.id + '';	// 左边自动关联, 如果左边没有，则无效果

            // 防止重复打开 
            const route = router.currentRoute;
            if(route.value.path === tab.path) {
                return;
            }
            
            // path 跳转
            router.push(tab.path);

            // 调整一下滚动条
            nextTick(function() {
                mitt.emit('scrollToAuto');
            })
        },
        // 显示一个选项卡, 根据 id , 不存在则不显示
        showTabById: function(id) {
            const tab = this.getTabById(id);
            if(tab) {
                this.showTab(tab);
                return tab;
            }
        },

        // 创建一个新的 tab view 并显示 
        showTempView: function (id, title, component, meta) {
            this.showTempTabView({
                id: id,
                title: title,
                component: component,
                auth: false,
                meta: meta
            })
        },
        // 创建一个新的 tab view 并显示 
        showTempTabView: function (tab) {
            // 规范属性定义 
            tab = defineMenu([tab])[0];
            
            // 如果已经存在，则直接显示 
            const tabSe = this.getTabById(tab.id);
            if(tabSe) {
                this.showTab(tabSe);
                return;
            }

            // 如果是一个函数 
            if(typeof tab.component === 'function') {
                tab.component = tab.component();
            }
            
            // 否则，现场添加并显示 
            tab.component.then(com => {
                // console.log('解析：', com.default)
                com.default.name = tab.name;

                // 添加到路由集合 
                const route = {
                    name: tab.name,
                    path: tab.path,
                    component: com.default,
                    meta: {
                        ... (tab.meta || {}),
                        menu: tab
                    },
                };
                router.addRoute('layout', route);
                
                // 并显示 
                this.showTab(tab);
            });
        },
        
        // 关闭 tab （带动画）
        closeTab: function(tab, callFn) {

            // homeTab不能关闭
            if(tab === this.homeTab || tab.hideClose){
                return;
            }

            // 执行关闭动画
            var div = document.querySelector('#tab-' + tab.id);
            div.style.width = div.offsetWidth + 'px';
            setTimeout(function() {
                div.style.width = '0px';
            }, 0);

            // 等待动画结束
            setTimeout(function() {

                // 如果 tab 为当前正在显示的 tab, 则切换为前一个 tab
                if(tab === this.nativeTab) {
                    var index = this.tabList.indexOf(tab);
                    var preTab = this.tabList[index - 1];
                    if(preTab) {
                        this.showTab(preTab);
                    } else {
                        var nextTab = this.tabList[index + 1];
                        this.showTab(nextTab);
                    }
                }
                // 从 tabList 中移除这个 tab
                arrayDelete(this.tabList, tab);
                arrayDelete(this.viewNameList, tab.name);
                // 这里需要将div的属性复原，否则会有div转移的bug，初步怀疑是由 vuedraggable 或者 vue3 引起的
                if(div) {
                    div.style.width = '';
                }
                // 如果有回调
                if(callFn) {
                    nextTick(function() {
                        callFn();
                    })
                }
            }.bind(this), 150);
        },
        // 关闭 tab, 根据 id
        closeTabById: function(id, callFn) {
            var tab = this.getTabById(id);
            if(tab) {
                this.closeTab(tab, callFn);
            }
        },
        // 新窗口打开 tab
        newWinTab: function(tab) {
            open(tab.url)
        },

        // ------------------- 其它操作 --------------------
        // 展开菜单栏
        startOpen: function() {
            this.isOpen = true;
            // setTimeout(function (){
            //     useComStore().winResize();
            // }, 500)
        },
        // 折叠菜单栏
        endOpen: function() {
            this.isOpen = false;
            // setTimeout(function (){
            //     useComStore().winResize();
            // }, 500)
        },
        // 显示全局loading……
        showOsLoading: function (msg) {
            this.isOsLoading = true;
            this.osLoadingMsg = msg || '';
        },
        // 隐藏全局loading
        hideOsLoading: function () {
            this.isOsLoading = false;
        },
        // 隐藏全局loading (msg为空时才关闭，可以保证loading动画的连续性)
        hideOsLoading2: function () {
            setTimeout(function (){
                if(this.osLoadingMsg === '') {
                    this.isOsLoading = false;
                }
            }.bind(this),200)
        }
    }
})
