import SwiftUI

/// T-iPad-2 · size-class 驱动的单一根视图。按 `LayoutPolicy.mode` 在 compact
/// 宽度（iPhone / iPad Slide Over）选 `StackRootView`（现有路径，字节级不变）、
/// 在 regular 宽度（iPad 全屏 / 大分屏 / Stage Manager 大窗）选 `SplitRootView`
/// （分栏）。
///
/// **横切布线只声明一次、两分支共享**（PLAN_IOS_IPAD §5 T-iPad-2）：
/// - 隐私遮罩：ZStack 的**最顶层**，覆盖整棵导航树（含 split detail 的终端
///   字节）——`scenePhase != .active` 即遮（安全不变式，见 `PrivacyShadePolicy`）。
///   上提到这里，split detail 与 stack push 同样被遮，无遗漏。
/// - `.task` bootstrap / `.onChange(scenePhase)` / `.onOpenURL` / deep-link 提示
///   alert / add-host sheet / Projects sheet：全部设备无关，原样从旧 `RootView`
///   搬到这一层，故 compact 分支拿到与适配前完全一致的横切行为。
///
/// size class 是**运行时可变量**（iPad 拉出 Slide Over 立刻 regular→compact），
/// 所以这不是两套 UI 分叉，而是同一次运行内的自适应切换：`terminalController`
/// 归 `AppCoordinator` 所有，与布局分支正交，切换时不重建（T-iOS-29 `.id`
/// 稳定性的前提）。
struct AdaptiveRootView: View {
    @Bindable var coordinator: AppCoordinator
    @Environment(\.scenePhase) private var scenePhase
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass

    var body: some View {
        ZStack {
            layoutBranch
            if PrivacyShadePolicy.isShadeVisible(for: scenePhase) {
                PrivacyShadeView()
            }
        }
        .task { await coordinator.bootstrap() }
        .onChange(of: scenePhase) { _, phase in
            coordinator.handleScenePhase(phase)
        }
        .onOpenURL { coordinator.handleDeepLink(url: $0) } // T-iOS-22
        .alert(DeepLinkCopy.hintTitle, isPresented: deepLinkHintBinding) {
            Button(DeepLinkCopy.hintConfirm) { coordinator.deepLink.clearHint() }
        } message: {
            Text(coordinator.deepLink.hintMessage ?? "")
        }
        .sheet(
            isPresented: $coordinator.isAddHostPresented,
            onDismiss: { coordinator.addHostDismissed() }
        ) {
            addHostSheet
        }
        .sheet(
            isPresented: $coordinator.isProjectsPresented,
            onDismiss: { coordinator.projectsDismissed() }
        ) {
            projectsSheet
        }
        .sheet(isPresented: $coordinator.isDeviceCertPresented) {
            deviceCertSheet
        }
        .sheet(
            isPresented: $coordinator.isEnrollmentPresented,
            onDismiss: { coordinator.enrollmentDismissed() }
        ) {
            enrollmentSheet
        }
    }

    // MARK: - Layout branch (the SOLE size-class consumer)

    @ViewBuilder private var layoutBranch: some View {
        // Split only makes sense once we're in the session list. `.loading` and
        // `.pairing` (genuine iPad first-run, no paired host) get the full-screen
        // stack flow regardless of size class — a split sidebar has nothing to
        // list yet and would strand the user on the not-paired empty state
        // (T-iPad-5 finding). Route-gate the split branch.
        switch LayoutPolicy.mode(horizontalSizeClass: horizontalSizeClass) {
        case .split where coordinator.route == .sessions:
            SplitRootView(coordinator: coordinator)
        default:
            StackRootView(coordinator: coordinator)
        }
    }

    // MARK: - Deep-link hint alert (T-iOS-22)

    /// unknown host / store failure 提示（同旧 `RootView`）。
    private var deepLinkHintBinding: Binding<Bool> {
        Binding(
            get: { coordinator.deepLink.hintMessage != nil },
            set: { presented in
                guard !presented else { return }
                coordinator.deepLink.clearHint()
            }
        )
    }

    // MARK: - Add-host sheet (multi-host entry, list header)

    @ViewBuilder private var addHostSheet: some View {
        if let viewModel = coordinator.addHostPairingViewModel {
            NavigationStack {
                PairingScreen(viewModel: viewModel) { host in
                    coordinator.completeAddHost(host)
                }
            }
        }
    }

    // MARK: - Projects sheet (T-iOS-26)

    /// 自带 NavigationStack：列表 → 详情 → 差异都在 sheet 内 push；
    /// "在此仓库开新会话" 关掉 sheet 并在根导航开终端。
    @ViewBuilder private var projectsSheet: some View {
        if let viewModel = coordinator.projectsViewModel {
            NavigationStack {
                ProjectsScreen(viewModel: viewModel) { request in
                    coordinator.openProject(request)
                }
            }
        }
    }

    // MARK: - Device certificate sheet (C-iOS-3, HIGH reachability fix)

    /// 自带 NavigationStack（`ClientCertScreen` 用 `.navigationTitle`）+ 右上「完成」
    /// 关闭按钮，保证导入 .p12 后能明确返回。`ClientCertScreen` 自持
    /// `ClientCertViewModel`（keychain store），此处零依赖注入。
    @ViewBuilder private var deviceCertSheet: some View {
        NavigationStack {
            ClientCertScreen()
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button(RootCopy.done) { coordinator.isDeviceCertPresented = false }
                    }
                }
        }
    }

    // MARK: - Device enrollment sheet (B3, zero-.p12 auto-cert)

    /// 自带 NavigationStack + 右上「完成」。VM 由 coordinator 每次进入构建
    /// （`presentEnrollment`）；关闭后 `enrollmentDismissed` 丢弃 VM 并跑一次轮换。
    @ViewBuilder private var enrollmentSheet: some View {
        if let viewModel = coordinator.enrollmentViewModel {
            NavigationStack {
                EnrollmentScreen(model: viewModel)
                    .toolbar {
                        ToolbarItem(placement: .topBarTrailing) {
                            Button(RootCopy.done) { coordinator.isEnrollmentPresented = false }
                        }
                    }
            }
        }
    }
}
