//
//  HomeMoreFunctionsView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/22.
//

import SwiftUI

/// 首页全部功能视图，展示常用应用和当前角色拥有的更多功能。
struct HomeMoreFunctionsView: View {
    @Environment(PermissionContext.self) private var permissionContext
    @Environment(AppRouter.self) private var appRouter
    @Environment(RouterPath.self) private var router
    @Environment(\.dismiss) private var dismiss

    @State private var viewModel = HomeViewModel()
    @State private var commonUris: [String] = []

    private let commonMenuStore = HomeCommonMenuStore()

    private var commonItems: [HomeMenuItem] {
        commonUris.compactMap(menuItem(for:))
    }

    private var moreItems: [HomeMenuItem] {
        viewModel.menuItems.filter { item in
            !isCommonURI(item.uri)
        }
    }

    var body: some View {
        VStack(spacing: 0) {
            topBar

            ScrollView {
                VStack(alignment: .leading, spacing: 26) {
                    section(title: "常用应用", items: commonItems, isCommon: true)
                    section(title: "更多功能", items: moreItems, isCommon: false)
                }
                .padding(.horizontal, AppMetrics.Spacing.mediumLarge)
                .padding(.top, AppMetrics.Spacing.xxLarge + 1)
                .padding(.bottom, AppMetrics.Spacing.xxLarge)
            }
            .background(Color(hex: 0xF5F5F5))
        }
        .background(Color(hex: 0xF5F5F5).ignoresSafeArea())
        .toolbar(.hidden, for: .navigationBar)
        .task {
            rebuildMenus()
        }
        .onChange(of: permissionContext.currentRole?.id) { _, _ in
            rebuildMenus()
        }
        .onChange(of: permissionContext.rolePermissions.count) { _, _ in
            rebuildMenus()
        }
    }

    private var topBar: some View {
        ZStack {
            Text("全部功能")
                .font(.system(size: AppMetrics.FontSize.title2 + 1, weight: .semibold))
                .foregroundStyle(Color(hex: 0x2C2C2C))
                .frame(maxWidth: .infinity)

            HStack {
                Button {
                    dismiss()
                } label: {
                    Image(systemName: "chevron.left")
                        .font(.system(size: AppMetrics.FontSize.body, weight: .semibold))
                        .foregroundStyle(Color(hex: 0x111827))
                        .frame(width: AppMetrics.ControlSize.iconTapArea, height: AppMetrics.ControlSize.iconTapArea)
                }
                .buttonStyle(.plain)

                Spacer()
            }
            .padding(.horizontal, AppMetrics.Spacing.pageHorizontal)
        }
        .frame(height: 62)
        .background(.white)
        .overlay(alignment: .bottom) {
            Rectangle()
                .fill(Color.black.opacity(0.06))
                .frame(height: 0.5)
        }
    }

    private func section(title: String, items: [HomeMenuItem], isCommon: Bool) -> some View {
        VStack(alignment: .leading, spacing: AppMetrics.Spacing.medium) {
            Text(title)
                .font(.system(size: AppMetrics.FontSize.title, weight: .bold))
                .foregroundStyle(Color(hex: 0x2C2C2C))

            appGrid(items: items, isCommon: isCommon)
        }
    }

    private func appGrid(items: [HomeMenuItem], isCommon: Bool) -> some View {
        LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 14), count: 3), spacing: AppMetrics.Spacing.mediumLarge) {
            ForEach(items, id: \.uri) { item in
                ZStack(alignment: .topTrailing) {
                    Button {
                        openMenu(item)
                    } label: {
                        VStack(spacing: AppMetrics.Spacing.mediumLarge + 1) {
                            menuIconView(for: item)
                                .frame(width: 34, height: 34)

                            Text(item.title)
                                .font(.system(size: AppMetrics.FontSize.callout))
                                .foregroundStyle(Color(hex: 0x252525))
                                .lineLimit(1)
                                .minimumScaleFactor(0.78)
                        }
                        .frame(maxWidth: .infinity)
                        .frame(height: 112)
                        .background(.white, in: RoundedRectangle(cornerRadius: 8))
                    }
                    .buttonStyle(.plain)

                    Button {
                        if isCommon {
                            commonUris = commonMenuStore.remove(item.uri, current: commonUris)
                        } else {
                            commonUris = commonMenuStore.add(item.uri, current: commonUris, menuItems: viewModel.menuItems)
                        }
                    } label: {
                        Image(systemName: isCommon ? "minus.circle.fill" : "plus.circle.fill")
                            .font(.system(size: 24, weight: .bold))
                            .foregroundStyle(isCommon ? Color(hex: 0xFF1111) : AppDesign.primary)
                            .background(Color.white, in: Circle())
                    }
                    .buttonStyle(.plain)
                    .offset(x: 9, y: -9)
                }
                .frame(maxWidth: .infinity)
                .frame(height: 112)
            }
        }
    }

    @ViewBuilder
    private func menuIconView(for item: HomeMenuItem) -> some View {
        RemoteImage(urlString: item.iconSrc, contentMode: .fit) {
            fallbackMenuIcon(for: item.uri)
        }
    }

    private func fallbackMenuIcon(for uri: String) -> some View {
        Image(systemName: HomeIconCatalog.iconName(for: uri))
            .resizable()
            .scaledToFit()
            .foregroundStyle(AppDesign.primary)
            .frame(width: 34, height: 34)
    }

    private func menuItem(for uri: String) -> HomeMenuItem? {
        let availableURIs = Set(viewModel.menuItems.map(\.uri))
        let resolvedUri = HomeMenuRouter.canonicalURI(for: uri, availableURIs: availableURIs)
        guard let existing = viewModel.menuItems.first(where: { $0.uri == resolvedUri }) else {
            return nil
        }
        return HomeMenuItem(
            title: HomeMenuRouter.displayTitle(for: resolvedUri, fallback: existing.title),
            uri: resolvedUri,
            iconSrc: existing.iconSrc
        )
    }

    private func isCommonURI(_ uri: String) -> Bool {
        let aliasKey = HomeMenuRouter.menuAliasKey(for: uri)
        return commonUris.contains { HomeMenuRouter.menuAliasKey(for: $0) == aliasKey }
    }

    private func openMenu(_ item: HomeMenuItem) {
        switch HomeMenuRouter.resolve(uri: item.uri, title: item.title) {
        case .tab(let tab):
            appRouter.select(tab)
        case .orders(let entry):
            appRouter.selectOrders(entry: entry)
        case .destination(let route):
            if route == .moreFunctions {
                return
            }
            router.navigate(to: .home(route))
        case .unsupported(let uri, let title, _):
            router.navigate(to: .home(.modulePlaceholder(uri: uri, title: title)))
        case .placeholder(let uri, let title):
            HomeRouteDiagnostics.recordUnknown(uri: uri, title: title)
            router.navigate(to: .home(.modulePlaceholder(uri: uri, title: title)))
        }
    }

    private func rebuildMenus() {
        viewModel.buildMenus(
            from: permissionContext.rolePermissions,
            currentRoleId: permissionContext.currentRole?.id
        )
        commonUris = commonMenuStore.load(menuItems: viewModel.menuItems)
    }
}
