import Foundation import UIKit import SwiftUI @main struct HermesApp: App { @StateObject private var repository = HermesRepository( apiClient: HermesAPIClient( environment: APIEnvironment(baseURL: URL(string: "http://localhost:3000/")!) ) ) @StateObject private var analytics = HermesAnalyticsClient() @StateObject private var playerCoordinator = PlayerCoordinator() @State private var isBootstrapping = false @State private var appMode: HermesAppMode = .demo var body: some Scene { WindowGroup { RootView( mode: appMode, onModeSelected: { selectedMode in guard appMode != selectedMode else { return } appMode = selectedMode repository.reset() }, onStartSession: { localeCode, selectedMode in if selectedMode == .demo { Task { @MainActor in repository.reset() await repository.bootstrapMock( localeCode: localeCode, appVersion: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.1.0" ) analytics.track("session_started", attributes: ["screen_name": "session", "locale_code": localeCode, "mode": selectedMode.rawValue]) } return } if repository.currentSession != nil, repository.currentRound != nil { return } guard !isBootstrapping else { return } isBootstrapping = true let request = HermesSessionStartRequest( localeCode: localeCode, devicePlatform: "ios", deviceModel: UIDevice.current.model, osVersion: UIDevice.current.systemVersion, appVersion: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.1.0" ) analytics.track("session_start_requested", attributes: ["screen_name": "session", "locale_code": localeCode, "mode": selectedMode.rawValue]) Task { @MainActor in defer { isBootstrapping = false } do { _ = try await repository.bootstrap(request) analytics.track("session_started", attributes: ["screen_name": "session", "locale_code": localeCode, "mode": selectedMode.rawValue]) await analytics.flush(using: repository) } catch { analytics.track("session_start_failed", attributes: ["screen_name": "session", "locale_code": localeCode, "mode": selectedMode.rawValue]) } } } ) .preferredColorScheme(.dark) .tint(HermesTheme.accent) .environmentObject(analytics) .environmentObject(repository) .environmentObject(playerCoordinator) } } }