//
//  AllFunctionsViewModelTests.swift
//  suixinkanTests
//

import UIKit
import XCTest
@testable import suixinkan

/// 全部功能 ViewModel 测试。
final class AllFunctionsViewModelTests: XCTestCase {

    private var defaults: UserDefaults!
    private var appStore: AppStore!
    private var menuStore: HomeCommonMenuStore!

    override func setUp() {
        defaults = UserDefaults(suiteName: "AllFunctionsViewModelTests")!
        defaults.removePersistentDomain(forName: "AllFunctionsViewModelTests")
        appStore = AppStore(defaults: defaults)
        menuStore = HomeCommonMenuStore(defaults: defaults)
        appStore.session.userId = "1001"
        appStore.session.accountType = .scenicUser
        appStore.session.roleCode = AppRoleCode.photographer.rawValue
    }

    override func tearDown() {
        defaults.removePersistentDomain(forName: "AllFunctionsViewModelTests")
        super.tearDown()
    }

    func testLoadFunctionsUsesDefaultFirstFourAndExcludesMessageCenter() {
        appStore.permissions.savePermissionItems([
            HomePermissionItem(id: "1", name: "钱包", uri: "wallet"),
            HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"),
            HomePermissionItem(id: "3", name: "任务", uri: "task_management"),
            HomePermissionItem(id: "4", name: "设置", uri: "system_settings"),
            HomePermissionItem(id: "5", name: "消息", uri: "message_center"),
        ])
        let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore)

        viewModel.loadFunctions()

        XCTAssertEqual(viewModel.commonMenus.map(\.uri), [
            "wallet", "cloud_management", "task_management", "system_settings",
        ])
        XCTAssertTrue(viewModel.moreMenus.isEmpty)
        XCTAssertEqual(
            menuStore.savedCommonURIs(
                accountScope: appStore.session.accountCachePrefix,
                roleCode: appStore.session.roleCode
            ),
            ["wallet", "cloud_management", "task_management", "system_settings"]
        )
    }

    func testLoadFunctionsUsesSavedURIsOverDefault() {
        appStore.permissions.savePermissionItems([
            HomePermissionItem(id: "1", name: "钱包", uri: "wallet"),
            HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"),
            HomePermissionItem(id: "3", name: "任务", uri: "task_management"),
        ])
        menuStore.saveCommonURIs(
            ["cloud_management"],
            accountScope: appStore.session.accountCachePrefix,
            roleCode: appStore.session.roleCode
        )
        let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore)

        viewModel.loadFunctions()

        XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["cloud_management"])
        XCTAssertEqual(Set(viewModel.moreMenus.map(\.uri)), Set(["wallet", "task_management"]))
    }

    func testAddToCommonMovesMenuAndPersists() {
        appStore.permissions.savePermissionItems([
            HomePermissionItem(id: "1", name: "钱包", uri: "wallet"),
            HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"),
        ])
        menuStore.saveCommonURIs(
            ["wallet"],
            accountScope: appStore.session.accountCachePrefix,
            roleCode: appStore.session.roleCode
        )
        let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore)
        viewModel.loadFunctions()
        let cloudMenu = viewModel.moreMenus.first { $0.uri == "cloud_management" }!

        viewModel.addToCommon(cloudMenu)

        XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["wallet", "cloud_management"])
        XCTAssertTrue(viewModel.moreMenus.isEmpty)
        XCTAssertTrue(viewModel.didCustomize)
        XCTAssertEqual(
            menuStore.savedCommonURIs(
                accountScope: appStore.session.accountCachePrefix,
                roleCode: appStore.session.roleCode
            ),
            ["wallet", "cloud_management"]
        )
    }

    func testRemoveFromCommonMovesMenuAndPersists() {
        appStore.permissions.savePermissionItems([
            HomePermissionItem(id: "1", name: "钱包", uri: "wallet"),
            HomePermissionItem(id: "2", name: "云盘", uri: "cloud_management"),
        ])
        menuStore.saveCommonURIs(
            ["wallet", "cloud_management"],
            accountScope: appStore.session.accountCachePrefix,
            roleCode: appStore.session.roleCode
        )
        let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore)
        viewModel.loadFunctions()
        let walletMenu = viewModel.commonMenus.first { $0.uri == "wallet" }!

        viewModel.removeFromCommon(walletMenu)

        XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["cloud_management"])
        XCTAssertEqual(viewModel.moreMenus.map(\.uri), ["wallet"])
        XCTAssertTrue(viewModel.didCustomize)
    }

    func testPhotographerReportMenuVisibleAndCanBeAddedToCommon() {
        appStore.permissions.savePermissionItems([
            HomePermissionItem(id: "1", name: "位置上报", uri: "location_report"),
            HomePermissionItem(id: "2", name: "举报摄影师", uri: "report_photographer"),
        ])
        menuStore.saveCommonURIs(
            ["location_report"],
            accountScope: appStore.session.accountCachePrefix,
            roleCode: appStore.session.roleCode
        )
        let viewModel = AllFunctionsViewModel(appStore: appStore, commonMenuStore: menuStore)

        viewModel.loadFunctions()

        XCTAssertEqual(HomeMenuCatalog.item(for: "report_photographer")?.title, "举报摄影师")
        XCTAssertEqual(viewModel.moreMenus.map(\.uri), ["report_photographer"])

        let menu = viewModel.moreMenus[0]
        viewModel.addToCommon(menu)

        XCTAssertEqual(viewModel.commonMenus.map(\.uri), ["location_report", "report_photographer"])
    }
}

/// 全部功能菜单卡片交互语义测试。
@MainActor
final class AllFunctionMenuCellTests: XCTestCase {

    func testAddStyleUsesWholeCellAsAccessibleActionWithoutNestedButton() {
        let cell = AllFunctionMenuCell(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        let menu = HomeMenuItem(uri: "wallet", title: "钱包", iconName: "wallet.pass")

        cell.apply(menu: menu, actionStyle: .add)

        XCTAssertTrue(cell.isAccessibilityElement)
        XCTAssertEqual(cell.accessibilityLabel, "钱包")
        XCTAssertEqual(cell.accessibilityHint, "添加到常用应用")
        XCTAssertTrue(cell.accessibilityTraits.contains(.button))
        XCTAssertFalse(containsButton(in: cell.contentView))
    }

    func testRemoveStyleDescribesWholeCellRemoveAction() {
        let cell = AllFunctionMenuCell(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        let menu = HomeMenuItem(uri: "wallet", title: "钱包", iconName: "wallet.pass")

        cell.apply(menu: menu, actionStyle: .remove)

        XCTAssertEqual(cell.accessibilityHint, "移出常用应用")
        XCTAssertTrue(cell.accessibilityTraits.contains(.button))
        XCTAssertFalse(containsButton(in: cell.contentView))
    }

    private func containsButton(in view: UIView) -> Bool {
        view is UIButton || view.subviews.contains(where: containsButton(in:))
    }
}
