//
//  RootView.swift
//  suixinkan
//
//  Created by Codex on 2026/6/18.
//

import SwiftUI

/// App 根视图，负责创建全局依赖并根据登录状态切换登录页和主界面。
struct RootView: View {
    @State private var appSession = AppSession()
    @State private var accountContext = AccountContext()
    @State private var permissionContext = PermissionContext()
    @State private var scenicSpotContext = ScenicSpotContext()
    @State private var appRouter = AppRouter()
    @State private var toastCenter = ToastCenter()
    @State private var globalLoading = GlobalLoadingCenter()
    @State private var snapshotStore: AccountSnapshotStore
    @State private var apiClient: APIClient
    @State private var authAPI: AuthAPI
    @State private var profileAPI: ProfileAPI
    @State private var uploadAPI: UploadAPI
    @State private var ossUploadService: OSSUploadService
    @State private var accountContextAPI: AccountContextAPI
    @State private var ordersAPI: OrdersAPI
    @State private var statisticsAPI: StatisticsAPI
    @State private var paymentAPI: PaymentAPI
    @State private var walletAPI: WalletAPI
    @State private var scenicPermissionAPI: ScenicPermissionAPI
    @State private var authSessionCoordinator: AuthSessionCoordinator
    @State private var sessionBootstrapper: SessionBootstrapper

    /// 初始化网络客户端和业务 API，确保它们共享同一个 token provider。
    init() {
        let apiClient = APIClient()
        let tokenStore = SessionTokenStore()
        let snapshotStore = AccountSnapshotStore()
        _snapshotStore = State(initialValue: snapshotStore)
        _apiClient = State(initialValue: apiClient)
        _authAPI = State(initialValue: AuthAPI(client: apiClient))
        _profileAPI = State(initialValue: ProfileAPI(client: apiClient))
        let uploadAPI = UploadAPI(client: apiClient)
        _uploadAPI = State(initialValue: uploadAPI)
        _ossUploadService = State(initialValue: OSSUploadService(configService: uploadAPI))
        _accountContextAPI = State(initialValue: AccountContextAPI(client: apiClient))
        _ordersAPI = State(initialValue: OrdersAPI(client: apiClient))
        _statisticsAPI = State(initialValue: StatisticsAPI(client: apiClient))
        _paymentAPI = State(initialValue: PaymentAPI(client: apiClient))
        _walletAPI = State(initialValue: WalletAPI(client: apiClient))
        _scenicPermissionAPI = State(initialValue: ScenicPermissionAPI(client: apiClient))
        _authSessionCoordinator = State(
            initialValue: AuthSessionCoordinator(
                tokenStore: tokenStore,
                snapshotStore: snapshotStore,
                preferencesStore: AppPreferencesStore()
            )
        )
        _sessionBootstrapper = State(
            initialValue: SessionBootstrapper(
                tokenStore: tokenStore,
                snapshotStore: snapshotStore
            )
        )
    }

    var body: some View {
        rootContent
            .globalToastOverlay()
            .globalLoadingOverlay(loadingCenter: globalLoading)
            .environment(appSession)
            .environment(accountContext)
            .environment(permissionContext)
            .environment(scenicSpotContext)
            .environment(appRouter)
            .environment(toastCenter)
            .environment(\.globalLoading, globalLoading)
            .environment(snapshotStore)
            .environment(apiClient)
            .environment(authAPI)
            .environment(profileAPI)
            .environment(uploadAPI)
            .environment(ossUploadService)
            .environment(accountContextAPI)
            .environment(ordersAPI)
            .environment(statisticsAPI)
            .environment(paymentAPI)
            .environment(walletAPI)
            .environment(scenicPermissionAPI)
            .environment(authSessionCoordinator)
            .task {
                apiClient.bindAuthTokenProvider { appSession.token }
                await globalLoading.withLoading {
                    await sessionBootstrapper.restore(
                        appSession: appSession,
                        accountContext: accountContext,
                        permissionContext: permissionContext,
                        profileAPI: profileAPI,
                        accountContextAPI: accountContextAPI,
                        toastCenter: toastCenter
                    )
                }
            }
            .task(id: scenicSpotTaskID) {
                guard appSession.isLoggedIn else {
                    scenicSpotContext.reset()
                    return
                }
                await scenicSpotContext.reload(
                    scenicId: accountContext.currentScenic?.id,
                    api: accountContextAPI
                )
            }
            .onChange(of: appSession.phase) { _, phase in
                guard phase == .loggedOut else { return }
                accountContext.reset()
                permissionContext.reset()
                scenicSpotContext.reset()
                appRouter.reset()
                toastCenter.dismiss()
            }
    }

    @ViewBuilder
    private var rootContent: some View {
        switch appSession.phase {
        case .loggedOut:
            LoginView()
        case .restoring:
            Color(.systemBackground)
                .frame(maxWidth: .infinity, maxHeight: .infinity)
        case .loggedIn:
            MainTabsView()
        }
    }

    /// 景点加载任务的稳定标识，确保登录状态和当前景区变化都会触发任务。
    private var scenicSpotTaskID: String {
        let phaseText: String
        switch appSession.phase {
        case .loggedOut:
            phaseText = "loggedOut"
        case .restoring:
            phaseText = "restoring"
        case .loggedIn:
            phaseText = "loggedIn"
        }
        return "\(phaseText)-\(accountContext.currentScenic?.id ?? 0)"
    }
}

#Preview {
    RootView()
}
