import ForgejoKit
import SwiftData
import SwiftUI

@main
struct ForjiApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
    @Environment(\.scenePhase) private var scenePhase
    @AppStorage("notificationsEnabled") private var notificationsEnabled = false

    let sharedModelContainer: ModelContainer
    @State private var bootstrappedAuthService: AuthenticationService
    @State private var bootstrappedMultiInstanceManager: MultiInstanceManager?

    init() {
        let schema = Schema([ForgejoInstance.self])
        let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
        let container: ModelContainer
        do {
            container = try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError("Could not create ModelContainer: \(error)")
        }
        sharedModelContainer = container

        let auth = AuthenticationService()
        var multiManager: MultiInstanceManager?

        #if DEBUG
            let devServerURL = UserDefaults.standard.string(forKey: "dev_serverURL") ?? ""
            let skipBootstrap = UserDefaults.standard.bool(forKey: "dev_resetData")
                || UserDefaults.standard.bool(forKey: "dev_skipAutoLogin")
                || !devServerURL.isEmpty
        #else
            let skipBootstrap = false
        #endif

        if !skipBootstrap {
            let context = ModelContext(container)
            let defaultDescriptor = FetchDescriptor<ForgejoInstance>(
                predicate: #Predicate { $0.isDefault },
            )
            let allDescriptor = FetchDescriptor<ForgejoInstance>()
            let allInstances = (try? context.fetch(allDescriptor)) ?? []

            let defaultAllInstances = UserDefaults.standard.bool(forKey: "defaultAllInstances")
            if defaultAllInstances, allInstances.count > 1 {
                let manager = MultiInstanceManager()
                manager.bootstrap(instances: allInstances)
                if manager.isConnected {
                    multiManager = manager
                }
            } else {
                let instance = (try? context.fetch(defaultDescriptor).first)
                    ?? (allInstances.count == 1 ? allInstances.first : nil)
                if let instance {
                    auth.bootstrapSession(instance: instance)
                }
            }
        }

        _bootstrappedAuthService = State(initialValue: auth)
        _bootstrappedMultiInstanceManager = State(initialValue: multiManager)
    }

    var body: some Scene {
        WindowGroup {
            ContentView(
                authService: bootstrappedAuthService,
                multiInstanceManager: $bootstrappedMultiInstanceManager,
            )
            .environment(NavigationState.shared)
        }
        .modelContainer(sharedModelContainer)
        .onChange(of: scenePhase) { _, newPhase in
            guard notificationsEnabled else { return }
            switch newPhase {
            case .active:
                Task {
                    await NotificationPollingService.shared.startForegroundPolling(
                        modelContainer: sharedModelContainer,
                    )
                }
            case .background:
                Task {
                    await NotificationPollingService.shared.stopForegroundPolling()
                    BackgroundDownloadManager.shared.startDownloads()
                    NotificationPollingService.shared.scheduleBackgroundPoll()
                }
            default:
                break
            }
        }
    }
}
