import SwiftUI
import SwiftData
import OSLog
import UserNotifications
import UIKit

private let logger = Logger(subsystem: "nahbar", category: "App")
private let notificationLogger = Logger(subsystem: "nahbar", category: "Notification")

// MARK: - App Delegate
// Setzt den UNUserNotificationCenterDelegate damit Benachrichtigungen auch im
// Vordergrund als Banner angezeigt werden.
final class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self
        return true
    }

    /// Zeigt Benachrichtigungen auch an, wenn die App im Vordergrund läuft.
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        completionHandler([.banner, .sound])
    }
}

@main
struct NahbarApp: App {

    @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate

    // Static let stellt sicher, dass der Container exakt einmal erstellt wird –
    // unabhängig davon, wie oft body ausgewertet wird.
    private static let containerBuild = AppGroup.makeMainContainerWithMigration()
    private static var mainContainer: ModelContainer { containerBuild.0 }
    private static var containerFallback: ContainerFallback { containerBuild.1 }

    @StateObject private var callWindowManager = CallWindowManager.shared
    @StateObject private var appLockManager    = AppLockManager.shared
    @StateObject private var cloudSyncMonitor  = CloudSyncMonitor()
    @StateObject private var profileStore      = UserProfileStore.shared
    @StateObject private var eventLog          = AppEventLog.shared

    /// Shared tour coordinator — passed via environment to all views.
    @State private var tourCoordinator = TourCoordinator()

    @AppStorage("activeThemeID") private var activeThemeIDRaw: String = ThemeID.linen.rawValue
    @AppStorage("icloudSyncEnabled") private var icloudSyncEnabled: Bool = false

    @Environment(\.scenePhase) private var scenePhase
    @State private var showSplash = true
    @State private var showDegradedWarning = (NahbarApp.containerFallback == .inMemory)

    private var activeTheme: NahbarTheme {
        NahbarTheme.theme(for: ThemeID(rawValue: activeThemeIDRaw) ?? .linen)
    }

    var body: some Scene {
        WindowGroup {
            ZStack {
                ContentView(splashVisible: showSplash)
                    .environmentObject(callWindowManager)
                    .environmentObject(appLockManager)
                    .environmentObject(cloudSyncMonitor)
                    .environmentObject(profileStore)
                    .environmentObject(eventLog)
                    .environment(tourCoordinator)
                    // Verhindert Touch-Durchfall bei aktivem Splash- oder Lock-Screen
                    .allowsHitTesting(!showSplash && !appLockManager.isLocked)

                if appLockManager.isLocked && !showSplash {
                    AppLockView()
                        .environmentObject(appLockManager)
                        .transition(.opacity)
                        .zIndex(1)
                }

                if showSplash {
                    SplashView(onFinished: {
                        appLockManager.lockIfEnabled()
                        showSplash = false
                    })
                    .transition(.opacity)
                    .zIndex(2)
                }

                // Degraded-Mode-Banner: sichtbar wenn nur In-Memory-Store verfügbar
                if showDegradedWarning {
                    VStack {
                        DegradedModeBanner { showDegradedWarning = false }
                        Spacer()
                    }
                    .zIndex(3)
                }
            }
            .animation(.easeInOut(duration: 0.25), value: appLockManager.isLocked)
            .animation(.easeInOut(duration: 0.40), value: showSplash)
            .environment(\.nahbarTheme, activeTheme)
            .tint(activeTheme.accent)
            .onAppear {
                applyTabBarAppearance(activeTheme)
                cloudSyncMonitor.startMonitoring(iCloudEnabled: icloudSyncEnabled)
                AftermathNotificationManager.shared.registerCategory()
                logger.info("App gestartet. Container-Modus: \(String(describing: NahbarApp.containerFallback))")
                AppEventLog.shared.record("Container-Modus: \(NahbarApp.containerFallback)", level: .info, category: "Lifecycle")
            }
            .onChange(of: activeThemeIDRaw) { _, _ in applyTabBarAppearance(activeTheme) }
            .onChange(of: icloudSyncEnabled) { _, enabled in
                cloudSyncMonitor.startMonitoring(iCloudEnabled: enabled)
            }
        }
        .modelContainer(NahbarApp.mainContainer)
        .onChange(of: scenePhase) { _, phase in
            if phase == .background {
                appLockManager.lockIfEnabled()
            }
        }
    }

    private func applyTabBarAppearance(_ theme: NahbarTheme) {
        let bg       = UIColor(theme.backgroundPrimary).withAlphaComponent(0.88)
        let normal   = UIColor(theme.contentTertiary)
        let selected = UIColor(theme.accent)
        let border   = UIColor(theme.borderSubtle).withAlphaComponent(0.6)

        let item = UITabBarItemAppearance()
        item.normal.iconColor   = normal
        item.normal.titleTextAttributes   = [.foregroundColor: normal]
        item.selected.iconColor = selected
        item.selected.titleTextAttributes = [.foregroundColor: selected]

        let tabAppearance = UITabBarAppearance()
        tabAppearance.configureWithTransparentBackground()
        tabAppearance.backgroundColor = bg
        tabAppearance.shadowColor = border
        tabAppearance.stackedLayoutAppearance       = item
        tabAppearance.inlineLayoutAppearance        = item
        tabAppearance.compactInlineLayoutAppearance = item

        UITabBar.appearance().standardAppearance   = tabAppearance
        UITabBar.appearance().scrollEdgeAppearance = tabAppearance

        let navBg       = UIColor(theme.backgroundPrimary).withAlphaComponent(0.92)
        let titleColor  = UIColor(theme.contentPrimary)

        let navAppearance = UINavigationBarAppearance()
        navAppearance.configureWithTransparentBackground()
        navAppearance.backgroundColor = navBg
        navAppearance.shadowColor = border
        navAppearance.titleTextAttributes      = [.foregroundColor: titleColor]
        navAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor]

        UINavigationBar.appearance().standardAppearance   = navAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navAppearance
        UINavigationBar.appearance().compactAppearance    = navAppearance
        UINavigationBar.appearance().tintColor = selected
    }
}

// MARK: - Degraded Mode Banner

private struct DegradedModeBanner: View {
    let onDismiss: () -> Void

    var body: some View {
        HStack(spacing: 10) {
            Image(systemName: "exclamationmark.triangle.fill")
                .foregroundStyle(.orange)
            VStack(alignment: .leading, spacing: 1) {
                Text("Datenbankfehler")
                    .font(.system(size: 13, weight: .semibold))
                Text("Daten werden in dieser Sitzung nicht gespeichert.")
                    .font(.system(size: 11))
                    .foregroundStyle(.secondary)
            }
            Spacer()
            Button(action: onDismiss) {
                Image(systemName: "xmark")
                    .font(.system(size: 12, weight: .medium))
                    .foregroundStyle(.secondary)
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
        .background(.regularMaterial)
        .overlay(alignment: .bottom) {
            Rectangle()
                .fill(Color.orange.opacity(0.4))
                .frame(height: 1)
        }
    }
}
