//
//  MainTabBarController.swift
//  suixinkan
//

import UIKit

/// 主 Tab 容器，展示四个一级入口及中间扫码按钮。
final class MainTabBarController: UITabBarController {

    private let badgeViewModel = MainTabBadgeViewModel()
    private var tabNavigationControllers: [AppTab: TabNavigationController] = [:]
    private var isSyncingTabSelection = false

    private let scanHandler = MainTabScanHandler(api: NetworkServices.shared.orderAPI)

    /// 测试时可注入扫码点击处理。
    var onScanTabSelected: (() -> Void)?

    private enum TabSlot: CaseIterable {
        case home
        case orders
        case scan
        case statistics
        case profile

        var appTab: AppTab? {
            switch self {
            case .home: return .home
            case .orders: return .orders
            case .scan: return nil
            case .statistics: return .statistics
            case .profile: return .profile
            }
        }

        static func index(for tab: AppTab) -> Int? {
            allCases.firstIndex { $0.appTab == tab }
        }

        static var scanIndex: Int? {
            allCases.firstIndex(of: .scan)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
        configureTabBarAppearance()
        configureTabs()
        bindBadgeViewModel()
        bindScanHandler()
        badgeViewModel.refreshPendingWriteOffCount()
    }

    /// 选中指定主 Tab。
    func selectTab(_ tab: AppTab) {
        guard let index = TabSlot.index(for: tab) else { return }
        guard selectedIndex != index else { return }
        isSyncingTabSelection = true
        selectedIndex = index
        isSyncingTabSelection = false
        if tab == .orders {
            badgeViewModel.refreshPendingWriteOffCount()
        }
    }

    /// 响应推送点击，切换到目标 Tab 并打开对应业务页面。
    func openPushDestination(_ destination: PushDestination) {
        let targetTab = AppTab.home

        selectTab(targetTab)
        guard let navigationController = tabNavigationControllers[targetTab] else { return }
        _ = navigationController.popToRootViewController(animated: false)

        let controller: UIViewController?
        switch destination {
        case .paymentRecord:
            controller = PaymentCollectionRecordViewController()
        case .paymentDetails:
            controller = PaymentCollectionDetailsViewController()
        case .messageCenter:
            controller = MessageCenterViewController()
        }

        if let controller {
            navigationController.pushViewController(controller, animated: false)
        }
    }

    private func configureTabBarAppearance() {
        tabBar.tintColor = AppColor.primary
        tabBar.unselectedItemTintColor = AppColor.textTabInactive
        tabBar.backgroundColor = AppColor.cardBackground
        tabBar.shadowImage = UIImage()

        let normalAttributes: [NSAttributedString.Key: Any] = [
            .foregroundColor: AppColor.textTabInactive,
            .font: UIFont.app(.caption),
        ]
        let selectedAttributes: [NSAttributedString.Key: Any] = [
            .foregroundColor: AppColor.primary,
            .font: UIFont.app(.captionMedium),
        ]

        let appearance = UITabBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = AppColor.cardBackground
        appearance.shadowColor = AppColor.tabBarShadow
        appearance.stackedLayoutAppearance.normal.titleTextAttributes = normalAttributes
        appearance.stackedLayoutAppearance.selected.titleTextAttributes = selectedAttributes
        tabBar.standardAppearance = appearance
        tabBar.scrollEdgeAppearance = appearance
    }

    private func configureTabs() {
        tabNavigationControllers.removeAll()
        viewControllers = TabSlot.allCases.map { slot in
            if let tab = slot.appTab {
                let navigationController = TabNavigationController(tab: tab)
                navigationController.tabBarItem = tab.makeTabBarItem()
                tabNavigationControllers[tab] = navigationController
                return navigationController
            }

            let scannerPlaceholder = UIViewController()
            scannerPlaceholder.tabBarItem = MainScanTabItem.makeTabBarItem()
            return scannerPlaceholder
        }
    }

    private func bindBadgeViewModel() {
        badgeViewModel.onChange = { [weak self] in
            self?.updateOrderBadge()
        }
    }

    private func updateOrderBadge() {
        let badgeValue: String?
        if let count = badgeViewModel.pendingWriteOffCount, count > 0 {
            badgeValue = "\(count)"
        } else {
            badgeValue = nil
        }
        tabNavigationControllers[.orders]?.tabBarItem.badgeValue = badgeValue
    }

    private func bindScanHandler() {
        scanHandler.onShowMessage = { [weak self] message in
            self?.showScanToast(message)
        }
        scanHandler.onShowSignIn = { [weak self] response in
            guard let self else { return }
            OrderSignInAlertController.present(from: self, response: response)
        }
        scanHandler.onShowWriteOff = { [weak self] response in
            guard let self else { return }
            WriteOffResultAlertController.present(from: self, response: response)
        }
        scanHandler.onShowMultiVerifySheet = { [weak self] spots, selected in
            self?.presentMultiVerifySheet(spots: spots, selected: selected)
        }
        scanHandler.onNavigateBindAcquirer = { [weak self] saleUserId in
            self?.presentBindAcquirerAfterScan(saleUserId: saleUserId)
        }
    }

    private func presentBindAcquirerAfterScan(saleUserId: Int) {
        dismiss(animated: true) { [weak self] in
            guard let self else { return }
            let controller = BindAcquirerViewController(saleUserId: saleUserId)
            self.topNavigationController()?.pushViewController(controller, animated: true)
        }
    }

    private func topNavigationController() -> UINavigationController? {
        if let selected = selectedViewController as? UINavigationController {
            return selected
        }
        return selectedViewController?.navigationController
    }

    private func showScanToast(_ message: String) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        present(alert, animated: true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
            alert.dismiss(animated: true)
        }
    }

    private func presentMultiVerifySheet(spots: [MultiTravelScenicSpotEntity], selected: MultiTravelScenicSpotEntity?) {
        let controller = MultiVerifyScenicSpotViewController(spots: spots, selected: selected)
        controller.onConfirm = { [weak self] spot in
            guard let self, let pending = self.scanHandler.pendingMultiVerify else { return }
            Task { await self.scanHandler.confirmMultiVerify(pending: pending, spot: spot) }
        }
        let nav = UINavigationController(rootViewController: controller)
        nav.modalPresentationStyle = .pageSheet
        present(nav, animated: true)
    }

    private func presentGlobalScanner() {
        guard presentedViewController == nil else { return }

        let scanner = QRCodeScannerViewController()
        scanner.onScanResult = { [weak self] result in
            guard let self else { return }
            Task { await self.scanHandler.handleScanResult(result) }
        }
        let navigationController = UINavigationController(rootViewController: scanner)
        navigationController.modalPresentationStyle = .fullScreen
        present(navigationController, animated: true)
    }
}

extension MainTabBarController: UITabBarControllerDelegate {

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        guard viewControllers?.firstIndex(of: viewController) == TabSlot.scanIndex else {
            return true
        }

        if let onScanTabSelected {
            onScanTabSelected()
        } else {
            presentGlobalScanner()
        }
        return false
    }

    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        guard !isSyncingTabSelection,
              let navigationController = viewController as? TabNavigationController else { return }

        if navigationController.appTab == .orders {
            badgeViewModel.refreshPendingWriteOffCount()
        }
    }
}
