import Foundation import AppKit import os class ActiveWindowService: ObservableObject { static let shared = ActiveWindowService() @Published var currentApplication: NSRunningApplication? private var enhancementService: AIEnhancementService? private let browserURLService = BrowserURLService.shared private var whisperState: WhisperState? private let logger = Logger( subsystem: "com.prakashjoshipax.VoiceInk", category: "browser.detection" ) private init() {} func configure(with enhancementService: AIEnhancementService) { self.enhancementService = enhancementService } func configureWhisperState(_ whisperState: WhisperState) { self.whisperState = whisperState } func applyConfigurationForCurrentApp() async { guard PowerModeManager.shared.isPowerModeEnabled else { return } guard let frontmostApp = NSWorkspace.shared.frontmostApplication, let bundleIdentifier = frontmostApp.bundleIdentifier else { return } await MainActor.run { currentApplication = frontmostApp } if let browserType = BrowserType.allCases.first(where: { $0.bundleIdentifier == bundleIdentifier }) { logger.debug("🌐 Detected Browser: \(browserType.displayName)") do { logger.debug("📝 Attempting to get URL from \(browserType.displayName)") let currentURL = try await browserURLService.getCurrentURL(from: browserType) logger.debug("📍 Successfully got URL: \(currentURL)") if let config = PowerModeManager.shared.getConfigurationForURL(currentURL) { logger.debug("⚙️ Found URL Configuration: \(config.name) for URL: \(currentURL)") await MainActor.run { PowerModeManager.shared.setActiveConfiguration(config) } await applyConfiguration(config) return } else { logger.debug("📝 No URL configuration found for: \(currentURL)") } } catch { logger.error("❌ Failed to get URL from \(browserType.displayName): \(error.localizedDescription)") } } let config = PowerModeManager.shared.getConfigurationForApp(bundleIdentifier) ?? PowerModeManager.shared.defaultConfig await MainActor.run { PowerModeManager.shared.setActiveConfiguration(config) } await applyConfiguration(config) } /// Applies a specific configuration func applyConfiguration(_ config: PowerModeConfig) async { guard let enhancementService = enhancementService else { return } // Capture current state before making changes let wasScreenCaptureEnabled = await MainActor.run { enhancementService.useScreenCaptureContext } let wasEnhancementEnabled = await MainActor.run { enhancementService.isEnhancementEnabled } await MainActor.run { enhancementService.isEnhancementEnabled = config.isAIEnhancementEnabled enhancementService.useScreenCaptureContext = config.useScreenCapture if config.isAIEnhancementEnabled { if let promptId = config.selectedPrompt, let uuid = UUID(uuidString: promptId) { enhancementService.selectedPromptId = uuid } else { if let firstPrompt = enhancementService.allPrompts.first { enhancementService.selectedPromptId = firstPrompt.id } } } if config.isAIEnhancementEnabled, let aiService = enhancementService.getAIService() { if let providerName = config.selectedAIProvider, let provider = AIProvider(rawValue: providerName) { aiService.selectedProvider = provider if let model = config.selectedAIModel, !model.isEmpty { aiService.selectModel(model) } } } if let language = config.selectedLanguage { UserDefaults.standard.set(language, forKey: "SelectedLanguage") NotificationCenter.default.post(name: .languageDidChange, object: nil) } } if let whisperState = self.whisperState, let modelName = config.selectedWhisperModel { let models = await MainActor.run { whisperState.availableModels } if let selectedModel = models.first(where: { $0.name == modelName }) { let currentModelName = await MainActor.run { whisperState.currentModel?.name } if currentModelName != modelName { await whisperState.setDefaultModel(selectedModel) await whisperState.cleanupModelResources() do { try await whisperState.loadModel(selectedModel) } catch { } } } } // Wait for UI changes and model loading to complete first try? await Task.sleep(nanoseconds: 1_500_000_000) // 1.5 seconds // Then check if we should capture if config.isAIEnhancementEnabled && config.useScreenCapture { await enhancementService.captureScreenContext() } } }