/**
 * @description 动态路由生成器工具类
 * @author yslg
 * @since 2025-12-12
 * 
 * 说明：此文件提供路由生成的通用方法，各个 web 服务可以使用这些方法生成自己的路由
 */

import type { RouteRecordRaw } from 'vue-router'
import type { TbSysViewDTO } from '@/types'
import { ViewType } from '@/types'

// 为了代码可读性，创建类型别名
type SysMenu = TbSysViewDTO

/**
 * 路由生成器配置
 */
export interface RouteGeneratorConfig {
    /**
     * 布局组件映射表
     * key: 布局名称，value: 组件加载函数
     */
    layoutMap: Record<string, () => Promise<any>>
    
    /**
     * 视图组件加载器
     * 用于动态加载视图组件
     */
    viewLoader: (componentPath: string) => Promise<any> | null
    
    /**
     * 静态路由列表（可选）
     * 用于将静态路由转换为菜单项
     */
    staticRoutes?: RouteRecordRaw[]
    
    /**
     * 404 组件路径（可选）
     */
    notFoundComponent?: () => Promise<any>
}

/**
 * 根据菜单生成路由配置
 * @param menus 用户菜单列表
 * @param config 路由生成器配置
 * @returns Vue Router路由配置数组
 */
export function generateRoutes(
    menus: SysMenu[], 
    config: RouteGeneratorConfig
): RouteRecordRaw[] {
    if (!menus || menus.length === 0) {
        return []
    }
    
    const routes: RouteRecordRaw[] = []
    const pageRoutes: RouteRecordRaw[] = []
    
    // 构建菜单树
    const menuTree = buildMenuTree(menus, config.staticRoutes)
    
    // 生成路由
    menuTree.forEach(menu => {
        const route = generateRouteFromMenu(menu, config, true)
        
        if (route) {
            routes.push(route)
            
            // 递归提取所有 ROUTE 类型的子菜单
            extractPageChildren(route, pageRoutes, config)
        }
    })
    
    // 将 ROUTE 类型的路由添加到路由列表
    routes.push(...pageRoutes)
    
    return routes
}

/**
 * 递归提取路由中的 ROUTE 类型子菜单
 */
function extractPageChildren(
    route: any, 
    pageRoutes: RouteRecordRaw[], 
    config: RouteGeneratorConfig
) {
    // 检查当前路由是否有 ROUTE 类型的子菜单
    if (route.meta?.pageChildren && Array.isArray(route.meta.pageChildren)) {
        route.meta.pageChildren.forEach((pageMenu: SysMenu) => {
            const pageRoute = generateRouteFromMenu(pageMenu, config, true)
            if (pageRoute) {
                pageRoutes.push(pageRoute)
            } else {
                console.error(`[路由生成] 生成独立ROUTE路由失败: ${pageMenu.name}`)
            }
        })
        // 清理临时数据
        delete route.meta.pageChildren
    }
    
    // 递归检查子路由
    if (route.children && Array.isArray(route.children)) {
        route.children.forEach((childRoute: any) => {
            extractPageChildren(childRoute, pageRoutes, config)
        })
    }
}

/**
 * 根据单个菜单生成路由
 * @param menu 菜单对象
 * @param config 路由生成器配置
 * @param isTopLevel 是否是顶层菜单
 * @returns 路由配置
 */
function generateRouteFromMenu(
    menu: SysMenu, 
    config: RouteGeneratorConfig,
    isTopLevel = true
): RouteRecordRaw | null {
    // 跳过按钮类型
    if (menu.type === ViewType.BUTTON) {
        return null
    }
    
    // 跳过静态路由（已经在 router 中定义，不需要再次添加）
    if (menu.component === '__STATIC_ROUTE__') {
        return null
    }
    
    const route: any = {
        path: menu.url || `/${menu.viewId}`,
        name: menu.viewId,
        meta: {
            title: menu.name,
            icon: menu.icon,
            menuId: menu.viewId,
            parentId: menu.parentId,
            orderNum: menu.orderNum,
            type: menu.type,
            hideInMenu: false,
            requiresAuth: true,
        }
    }
    
    // 检查是否指定了布局（只有顶层菜单才使用布局）
    const layout = isTopLevel ? (menu as any).layout : null
    const hasChildren = menu.children && menu.children.length > 0
    
    // 检查 component 是否是布局组件
    const isComponentLayout = menu.component && (
        config.layoutMap[menu.component] || 
        (typeof menu.component === 'string' && menu.component.includes('Layout'))
    )
    
    // 确定路由组件
    if (layout && config.layoutMap[layout]) {
        // 如果指定了布局，使用指定的布局
        route.component = config.layoutMap[layout]
    } else if (isComponentLayout && hasChildren && isTopLevel && menu.component) {
        // 如果 component 是布局组件且有子菜单，使用该布局组件作为父路由组件
        route.component = config.layoutMap[menu.component]
    } else if (hasChildren && isTopLevel) {
        // 如果有子菜单但没有指定布局，根据菜单类型选择默认布局
        if (menu.type === ViewType.SIDEBAR && !menu.parentId) {
            route.component = config.layoutMap['SidebarLayout']
        } else {
            route.component = config.layoutMap['BasicLayout']
        }
    } else {
        // 没有子菜单，也没有指定布局，使用具体的页面组件
        if (menu.component) {
            const component = config.viewLoader(menu.component)
            if (component) {
                route.component = component
            } else {
                // 组件加载失败，使用 404
                route.component = config.notFoundComponent || (() => import('vue').then(({ h }) => ({
                    default: {
                        render() { return h('div', '404') }
                    }
                })))
            }
        } else {
            // 使用路由占位组件
            route.component = () => import('vue').then(({ h, resolveComponent }) => ({ 
                default: { 
                    render() { 
                        const RouterView = resolveComponent('RouterView')
                        return h(RouterView) 
                    } 
                } 
            }))
        }
    }
    
    // 处理子路由
    if (layout && config.layoutMap[layout] && menu.component && isTopLevel) {
        // 如果指定了布局，将页面组件作为子路由
        const component = config.viewLoader(menu.component)
        route.children = [{
            path: '',
            name: `${menu.viewId}_page`,
            component: component || route.component,
            meta: route.meta
        }]
        
        // 如果还有其他子菜单，继续添加
        if (hasChildren) {
            const pageChildren: SysMenu[] = []
            const normalChildren: SysMenu[] = []
            
            menu.children!.forEach((child: SysMenu) => {
                if (child.type === ViewType.ROUTE) {
                    pageChildren.push(child)
                } else {
                    normalChildren.push(child)
                }
            })
            
            // 添加普通子菜单
            normalChildren.forEach(child => {
                const childRoute = generateRouteFromMenu(child, config, false)
                if (childRoute) {
                    route.children!.push(childRoute)
                }
            })
            
            // ROUTE 类型的菜单保存到 meta
            if (pageChildren.length > 0) {
                route.meta.pageChildren = pageChildren
            }
        }
    } else if (hasChildren) {
        // 处理有子菜单的情况
        route.children = []
        
        // 分离 ROUTE 类型的子菜单和普通子菜单
        const pageChildren: SysMenu[] = []
        const normalChildren: SysMenu[] = []
        
        menu.children!.forEach((child: SysMenu) => {
            if (child.type === ViewType.ROUTE) {
                pageChildren.push(child)
            } else {
                normalChildren.push(child)
            }
        })

        // 如果当前菜单有组件且有普通子菜单，创建默认子路由
        if (menu.component && !isComponentLayout && normalChildren.length > 0) {
            const component = config.viewLoader(menu.component)
            route.children!.push({
                path: '',
                name: `${menu.viewId}_page`,
                component: component || route.component,
                meta: {
                    ...route.meta,
                }
            })
        }
        
        // 只将普通子菜单加入 children
        normalChildren.forEach(child => {
            const childRoute = generateRouteFromMenu(child, config, false)
            if (childRoute) {
                route.children!.push(childRoute)
            }
        })
        
        // PAGE 类型的菜单保存到 meta
        if (pageChildren.length > 0) {
            route.meta.pageChildren = pageChildren
        }
        
        // 自动重定向到第一个有URL的子菜单
        if (!route.redirect && route.children.length > 0) {
            const firstChildWithUrl = findFirstMenuWithUrl(normalChildren)
            if (firstChildWithUrl?.url) {
                route.redirect = firstChildWithUrl.url
            }
        }
    }

    return route
}

/**
 * 查找第一个有URL的菜单
 */
function findFirstMenuWithUrl(menus: SysMenu[]): SysMenu | null {
    for (const menu of menus) {
        if (menu.type !== ViewType.BUTTON) {
            if (menu.url) {
                return menu
            }
            if (menu.children && menu.children.length > 0) {
                const found = findFirstMenuWithUrl(menu.children)
                if (found) return found
            }
        }
    }
    return null
}

/**
 * 将静态路由转换为菜单项
 */
function convertRoutesToMenus(routes: RouteRecordRaw[]): SysMenu[] {
    const menus: SysMenu[] = []
    
    routes.forEach(route => {
        if (route.children && route.children.length > 0) {
            route.children.forEach(child => {
                if (child.meta?.type !== undefined) {
                    const menu: SysMenu = {
                        viewId: child.name as string || child.path.replace(/\//g, '-'),
                        parentId: '0',
                        name: child.meta.title as string || child.name as string,
                        url: route.path,
                        type: child.meta.type as number,
                        orderNum: (child.meta.orderNum as number) || -1,
                        component: '__STATIC_ROUTE__',
                    }
                    menus.push(menu)
                }
            })
        } else if (route.meta?.type !== undefined) {
            const menu: SysMenu = {
                viewId: route.name as string || route.path.replace(/\//g, '-'),
                parentId: '0',
                name: route.meta.title as string || route.name as string,
                url: route.path,
                type: route.meta.type as number,
                orderNum: (route.meta.orderNum as number) || -1,
                component: '__STATIC_ROUTE__',
            }
            menus.push(menu)
        }
    })
    
    return menus
}

/**
 * 构建菜单树结构
 * @param menus 菜单列表
 * @param staticRoutes 静态路由列表
 * @returns 菜单树
 */
export function buildMenuTree(
    menus: SysMenu[], 
    staticRoutes?: RouteRecordRaw[]
): SysMenu[] {
    // 将静态路由转换为菜单项
    const staticMenus = staticRoutes ? convertRoutesToMenus(staticRoutes) : []
    
    // 合并动态菜单和静态菜单
    const allMenus = [...staticMenus, ...menus]

    if (allMenus.length === 0) {
        return []
    }
    
    const menuMap = new Map<string, SysMenu>()
    const rootMenus: SysMenu[] = []
    const maxDepth = allMenus.length
    
    // 创建菜单映射
    allMenus.forEach(menu => {
        if (menu.viewId) {
            menuMap.set(menu.viewId, { ...menu, children: [] })
        }
    })
    
    // 循环构建树结构
    for (let depth = 0; depth < maxDepth; depth++) {
        let hasChanges = false
        
        allMenus.forEach(menu => {
            if (!menu.viewId) return
            
            const menuNode = menuMap.get(menu.viewId)
            if (!menuNode) return
            
            if (isNodeInTree(menuNode, rootMenus)) {
                return
            }
            
            if (!menu.parentId || menu.parentId === '0' || menu.parentId === '') {
                if (!isNodeInTree(menuNode, rootMenus)) {
                    rootMenus.push(menuNode)
                    hasChanges = true
                }
            } else {
                const parent = menuMap.get(menu.parentId)
                if (parent && isNodeInTree(parent, rootMenus)) {
                    if (!parent.children) {
                        parent.children = []
                    }
                    if (!parent.children.includes(menuNode)) {
                        parent.children.push(menuNode)
                        hasChanges = true
                    }
                }
            }
        })
        
        if (!hasChanges) {
            break
        }
    }
    
    // 排序
    const sortMenus = (menus: SysMenu[]): SysMenu[] => {
        return menus
            .sort((a, b) => (a.orderNum || 0) - (b.orderNum || 0))
            .map(menu => ({
                ...menu,
                children: menu.children ? sortMenus(menu.children) : []
            }))
    }
    
    return sortMenus(rootMenus)
}

/**
 * 检查节点是否已经在树中
 */
function isNodeInTree(node: SysMenu, tree: SysMenu[]): boolean {
    for (const treeNode of tree) {
        if (treeNode.viewId === node.viewId) {
            return true
        }
        if (treeNode.children && isNodeInTree(node, treeNode.children)) {
            return true
        }
    }
    return false
}

/**
 * 根据权限过滤菜单
 */
export function filterMenusByPermissions(
    menus: SysMenu[], 
    permissions: string[]
): SysMenu[] {
    if (!menus || menus.length === 0) {
        return []
    }
    
    return menus
        .filter(() => true) // 暂时返回true，后续可根据实际需求过滤
        .map(menu => {
            if (menu.children && menu.children.length > 0) {
                return {
                    ...menu,
                    children: filterMenusByPermissions(menu.children, permissions)
                }
            }
            return menu
        })
}

/**
 * 查找路由路径对应的菜单
 */
export function findMenuByPath(menus: SysMenu[], path: string): SysMenu | null {
    for (const menu of menus) {
        if (menu.url === path) {
            return menu
        }
        
        if (menu.children && menu.children.length > 0) {
            const found = findMenuByPath(menu.children, path)
            if (found) {
                return found
            }
        }
    }
    
    return null
}

/**
 * 获取菜单路径数组（面包屑导航用）
 */
export function getMenuPath(menus: SysMenu[], targetMenuId: string): SysMenu[] {
    const path: SysMenu[] = []
    
    function findPath(menuList: SysMenu[]): boolean {
        for (const menu of menuList) {
            path.push(menu)
            
            if (menu.viewId === targetMenuId) {
                return true
            }
            
            if (menu.children && menu.children.length > 0) {
                if (findPath(menu.children)) {
                    return true
                }
            }
            
            path.pop()
        }
        
        return false
    }
    
    findPath(menus)
    return path
}

/**
 * 获取第一个可访问的菜单URL（用于登录后跳转）
 */
export function getFirstAccessibleMenuUrl(menus: SysMenu[]): string | null {
    if (!menus || menus.length === 0) {
        return null
    }
    
    const firstMenu = findFirstMenuWithUrl(menus)
    return firstMenu?.url || '/home'
}

/**
 * 从 LocalStorage 加载用户视图数据
 * @param storageKey localStorage 的 key，默认为 'loginDomain'
 * @param viewsPath 视图数据在对象中的路径，默认为 'userViews'
 * @returns 视图列表，如果不存在返回 null
 */
export function loadViewsFromStorage(
    storageKey: string = 'loginDomain',
    viewsPath: string = 'userViews'
): TbSysViewDTO[] | null {
    try {
        const dataStr = localStorage.getItem(storageKey)
        
        if (!dataStr) {
            console.log(`[路由工具] LocalStorage 中没有 ${storageKey}`)
            return null
        }
        
        const data = JSON.parse(dataStr)
        
        // 支持嵌套路径，如 'user.views'
        const paths = viewsPath.split('.')
        let views = data
        
        for (const path of paths) {
            views = views?.[path]
        }
        
        if (views && Array.isArray(views) && views.length > 0) {
            console.log(`[路由工具] 从 LocalStorage 加载视图，数量: ${views.length}`)
            return views
        }
        
        console.log(`[路由工具] ${storageKey} 中没有 ${viewsPath} 或数据为空`)
        return null
    } catch (error) {
        console.error('[路由工具] 从 LocalStorage 加载视图失败:', error)
        return null
    }
}

/**
 * 生成简化的路由配置（用于直接添加到 router）
 * 相比 generateRoutes，这个方法生成的路由更适合动态添加到现有路由树
 * 
 * @param views 视图列表
 * @param config 路由生成器配置
 * @param options 额外选项
 * @returns 路由配置数组
 */
export interface GenerateSimpleRoutesOptions {
    /**
     * 是否作为根路由的子路由（路径去掉前导 /）
     */
    asRootChildren?: boolean
    
    /**
     * iframe 类型视图的占位组件
     */
    iframePlaceholder?: () => Promise<any>
    
    /**
     * 是否启用详细日志
     */
    verbose?: boolean
}

export function generateSimpleRoutes(
    views: TbSysViewDTO[],
    config: RouteGeneratorConfig,
    options: GenerateSimpleRoutesOptions = {}
): RouteRecordRaw[] {
    const {
        asRootChildren = false,
        iframePlaceholder,
        verbose = false
    } = options
    
    if (!views || views.length === 0) {
        if (verbose) console.warn('[路由生成] 视图列表为空')
        return []
    }
    
    if (verbose) {
        console.log('[路由生成] 开始生成路由，视图数量:', views.length)
    }
    
    // 构建视图树
    const viewTree = buildMenuTree(views)
    
    if (verbose) {
        console.log('[路由生成] 构建视图树，根节点数量:', viewTree.length)
    }
    
    const routes: RouteRecordRaw[] = []
    
    // 遍历根节点，生成路由
    viewTree.forEach(view => {
        const route = generateSimpleRoute(view, config, {
            asRootChild: asRootChildren,
            iframePlaceholder,
            verbose
        })
        
        if (route) {
            routes.push(route)
            if (verbose) {
                console.log('[路由生成] 已生成路由:', {
                    path: route.path,
                    name: route.name,
                    hasComponent: !!route.component,
                    childrenCount: route.children?.length || 0
                })
            }
        } else if (verbose) {
            console.warn('[路由生成] 跳过无效视图:', view.name)
        }
    })
    
    return routes
}

/**
 * 从单个视图生成简化路由
 */
function generateSimpleRoute(
    view: TbSysViewDTO,
    config: RouteGeneratorConfig,
    options: {
        asRootChild?: boolean
        iframePlaceholder?: () => Promise<any>
        verbose?: boolean
    } = {}
): RouteRecordRaw | null {
    const { asRootChild = false, iframePlaceholder, verbose = false } = options
    
    // 验证必要字段
    if (!view.viewId) {
        if (verbose) console.error('[路由生成] 视图缺少 viewId:', view)
        return null
    }
    
    // 判断是否是 iframe 类型
    const isIframe = (view as any).viewType === 'iframe' || !!(view as any).iframeUrl
    
    // 处理路径和组件
    let routePath = view.url || `/${view.viewId}`
    let component: any
    
    if (isIframe) {
        // iframe 类型：使用占位组件（用于显示iframe内容）
        // 路由路径使用 url 字段（应该设置为不冲突的路径，如 /app/workcase）
        component = iframePlaceholder || (() => import('vue').then(({ h }) => ({ 
            default: {
                render() { return h('div', { class: 'iframe-placeholder' }, 'Loading...') }
            }
        })))
    } else if (view.component) {
        // route 类型：加载实际组件
        component = config.viewLoader(view.component)
        if (!component) {
            if (verbose) console.warn('[路由生成] 组件加载失败:', view.component, '使用占位组件')
            // 使用占位组件，避免路由无效
            const errorMsg = `组件加载失败: ${view.component}`
            component = () => import('vue').then(({ h }) => ({ 
                default: {
                    render() { 
                        return h('div', { 
                            style: { padding: '20px', color: 'red' } 
                        }, errorMsg) 
                    }
                }
            }))
        }
    }
    
    // 根路径的子路由去掉前导斜杠
    if (asRootChild && routePath.startsWith('/')) {
        routePath = routePath.substring(1)
    }
    
    const hasChildren = view.children && view.children.length > 0
    
    if (verbose) {
        console.log('[路由生成] 视图信息:', {
            viewId: view.viewId,
            name: view.name,
            url: view.url,
            component: view.component,
            isIframe,
            hasChildren,
            childrenCount: view.children?.length || 0
        })
    }
    
    const route: any = {
        path: routePath,
        name: view.viewId,
        meta: {
            title: view.name || view.viewId,
            icon: view.icon,
            menuId: view.viewId,
            orderNum: view.orderNum,
            requiresAuth: true,
            isIframe,
            iframeUrl: (view as any).iframeUrl
        }
    }
    
    // 根据 component 和 children 的情况处理
    if (component && hasChildren) {
        // 有组件且有子视图：组件作为空路径子路由
        route.component = component
        route.children = [
            {
                path: '',
                name: `${view.viewId}_page`,
                component: component,
                meta: route.meta
            }
        ]
        
        // 添加其他子路由
        view.children!.forEach(childView => {
            const childRoute = generateSimpleRoute(childView, config, { 
                asRootChild: false, 
                iframePlaceholder,
                verbose 
            })
            if (childRoute) {
                route.children.push(childRoute)
            }
        })
    } else if (component && !hasChildren) {
        // 只有组件，没有子视图
        route.component = component
    } else if (!component && hasChildren) {
        // 没有组件，只有子视图（路由容器）
        route.component = () => import('vue').then(({ h, resolveComponent }) => ({ 
            default: { 
                render() { 
                    const RouterView = resolveComponent('RouterView')
                    return h(RouterView) 
                } 
            } 
        }))
        route.children = []
        
        // 添加子路由
        view.children!.forEach(childView => {
            const childRoute = generateSimpleRoute(childView, config, { 
                asRootChild: false, 
                iframePlaceholder,
                verbose 
            })
            if (childRoute) {
                route.children.push(childRoute)
            }
        })
        
        // 重定向到第一个子路由
        if (route.children.length > 0) {
            const firstChild = route.children[0]
            route.redirect = firstChild.path
        }
    } else {
        // 既没有组件也没有子视图
        if (verbose) {
            console.warn('[路由生成] 视图既无组件也无子视图:', view.name)
        }
        return null
    }
    
    // 处理layout：如果视图指定了layout，且不是作为Root的子路由，且有有效组件，需要包裹layout
    const viewLayout = (view as any).layout
    if (viewLayout && !asRootChild && route.component && config.layoutMap[viewLayout]) {
        if (verbose) {
            console.log('[路由生成] 为视图添加布局:', view.name, '布局:', viewLayout, '路径:', routePath)
        }
        
        // 创建layout路由，将原路由的组件作为其子路由
        const layoutRoute: RouteRecordRaw = {
            path: routePath,
            name: view.viewId,
            component: config.layoutMap[viewLayout],
            meta: {
                ...route.meta,
                layout: viewLayout  // 标记使用的布局
            },
            children: [
                {
                    path: '',
                    name: `${view.viewId}_content`,
                    component: route.component,
                    meta: route.meta
                }
            ]
        }
        
        // 如果原路由有其他children（子视图），也添加到layout路由的children中
        if (route.children && route.children.length > 0) {
            // 跳过第一个空路径的子路由（如果存在）
            const otherChildren = route.children.filter((child: any) => child.path !== '')
            if (otherChildren.length > 0) {
                layoutRoute.children!.push(...otherChildren)
            }
        }
        
        if (verbose) {
            console.log('[路由生成] Layout路由生成完成:', {
                path: layoutRoute.path,
                name: layoutRoute.name,
                childrenCount: layoutRoute.children?.length
            })
        }
        
        return layoutRoute
    }
    
    return route
}
