import SwiftUI
import KeyboardShortcuts

struct ConfigurationView: View {
    let mode: ConfigurationMode
    let powerModeManager: PowerModeManager
    var onDismiss: () -> Void
    @EnvironmentObject var enhancementService: AIEnhancementService
    @EnvironmentObject var aiService: AIService
    @EnvironmentObject private var transcriptionModelManager: TranscriptionModelManager
    @FocusState private var isNameFieldFocused: Bool

    @State private var configName: String = "Nieuwe Power Mode"
    @State private var selectedEmoji: String = "💼"
    @State private var isShowingEmojiPicker = false
    @State private var isShowingAppPicker = false
    @State private var isAIEnhancementEnabled: Bool
    @State private var selectedPromptId: UUID?
    @State private var selectedTranscriptionModelName: String?
    @State private var selectedLanguage: String?
    @State private var isTextFormattingEnabled = false
    @State private var removePunctuation = false
    @State private var lowercaseTranscription = false
    @State private var installedApps: [(url: URL, name: String, bundleId: String, icon: NSImage)] = []
    @State private var searchText = ""
    @State private var validationErrors: [PowerModeValidationError] = []
    @State private var showValidationAlert = false
    @State private var selectedAIProvider: String?
    @State private var selectedAIModel: String?
    @State private var selectedAppConfigs: [AppConfig] = []
    @State private var websiteConfigs: [URLConfig] = []
    @State private var newWebsiteURL: String = ""
    @State private var useScreenCapture = false
    @State private var autoSendKey: AutoSendKey = .none
    @State private var isDefault = false
    @State private var isShowingDeleteConfirmation = false
    @State private var powerModeConfigId: UUID = UUID()
    @State private var isTranscriptFormattingExpanded = false

    private var effectiveModelName: String? {
        selectedTranscriptionModelName ?? transcriptionModelManager.currentTranscriptionModel?.name
    }

    private var filteredApps: [(url: URL, name: String, bundleId: String, icon: NSImage)] {
        if searchText.isEmpty { return installedApps }
        return installedApps.filter { app in
            app.name.localizedCaseInsensitiveContains(searchText) ||
            app.bundleId.localizedCaseInsensitiveContains(searchText)
        }
    }

    private var canSave: Bool { !configName.isEmpty }

    private func languageSelectionDisabled() -> Bool {
        guard let selectedModelName = effectiveModelName,
              let model = transcriptionModelManager.allAvailableModels.first(where: { $0.name == selectedModelName })
        else { return false }
        return model.provider == .fluidAudio || model.provider == .gemini
    }

    private func availableLanguages(for model: any TranscriptionModel) -> [String: String] {
        TranscriptionLanguageSupport.languages(for: model)
    }

    private func useCompatibleLanguage(for model: any TranscriptionModel) {
        selectedLanguage = TranscriptionLanguageSupport.validLanguageOrFallback(
            selectedLanguage ?? UserDefaults.standard.string(forKey: "SelectedLanguage"),
            for: model
        )
    }

    init(mode: ConfigurationMode, powerModeManager: PowerModeManager, onDismiss: @escaping () -> Void) {
        self.mode = mode
        self.powerModeManager = powerModeManager
        self.onDismiss = onDismiss

        switch mode {
        case .add:
            let newId = UUID()
            _powerModeConfigId = State(initialValue: newId)
            _isAIEnhancementEnabled = State(initialValue: false)
            _selectedPromptId = State(initialValue: nil)
            _selectedTranscriptionModelName = State(initialValue: nil)
            _selectedLanguage = State(initialValue: nil)
            _isTextFormattingEnabled = State(initialValue: false)
            _removePunctuation = State(initialValue: false)
            _lowercaseTranscription = State(initialValue: false)
            _configName = State(initialValue: "")
            _selectedEmoji = State(initialValue: "✏️")
            _useScreenCapture = State(initialValue: false)
            _autoSendKey = State(initialValue: .none)
            _isDefault = State(initialValue: false)
            // Use UserDefaults directly since EnvironmentObjects aren't available in init
            _selectedAIProvider = State(initialValue: UserDefaults.standard.string(forKey: "selectedAIProvider"))
            _selectedAIModel = State(initialValue: nil)
            _isTranscriptFormattingExpanded = State(initialValue: false)
        case .edit(let config):
            // Fetch latest version in case config was modified elsewhere
            let latestConfig = powerModeManager.getConfiguration(with: config.id) ?? config
            _powerModeConfigId = State(initialValue: latestConfig.id)
            _isAIEnhancementEnabled = State(initialValue: latestConfig.isAIEnhancementEnabled)
            _selectedPromptId = State(initialValue: latestConfig.selectedPrompt.flatMap { UUID(uuidString: $0) })
            _selectedTranscriptionModelName = State(initialValue: latestConfig.selectedTranscriptionModelName)
            _selectedLanguage = State(initialValue: latestConfig.selectedLanguage)
            _isTextFormattingEnabled = State(initialValue: latestConfig.isTextFormattingEnabled)
            _removePunctuation = State(initialValue: latestConfig.removePunctuation)
            _lowercaseTranscription = State(initialValue: latestConfig.lowercaseTranscription)
            _configName = State(initialValue: latestConfig.name)
            _selectedEmoji = State(initialValue: latestConfig.emoji)
            _selectedAppConfigs = State(initialValue: latestConfig.appConfigs ?? [])
            _websiteConfigs = State(initialValue: latestConfig.urlConfigs ?? [])
            _useScreenCapture = State(initialValue: latestConfig.useScreenCapture)
            _autoSendKey = State(initialValue: latestConfig.autoSendKey)
            _isDefault = State(initialValue: latestConfig.isDefault)
            _selectedAIProvider = State(initialValue: latestConfig.selectedAIProvider)
            _selectedAIModel = State(initialValue: latestConfig.selectedAIModel)
            _isTranscriptFormattingExpanded = State(initialValue: latestConfig.isTextFormattingEnabled || latestConfig.removePunctuation || latestConfig.lowercaseTranscription)
        }
    }

    var body: some View {
        VStack(spacing: 0) {
            // Header
            HStack(spacing: ProatSpacing.s) {
                Text(mode.title)
                    .font(ProatFont.sectie)
                    .foregroundColor(.proatText1)

                Spacer()

                Button(action: onDismiss) {
                    Image(systemName: "xmark")
                        .font(.system(size: 14, weight: .medium))
                        .foregroundColor(.proatText2)
                        .padding(ProatSpacing.xs - 2)
                        .background(Color.proatBgSunken)
                        .clipShape(Circle())
                }
                .buttonStyle(.plain)
                .help("Sluiten")
            }
            .padding(.horizontal, ProatSpacing.l - 4)
            .padding(.vertical, ProatSpacing.m)
            .background(Color.proatBgRaised)
            .overlay(Divider().opacity(0.5), alignment: .bottom)

            Form {
                Section("Algemeen") {
                    HStack(spacing: 12) {
                        Button {
                            isShowingEmojiPicker.toggle()
                        } label: {
                            Text(selectedEmoji)
                                .font(.system(size: 22))
                                .frame(width: 32, height: 32)
                                .background(
                                    RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous)
                                        .fill(Color.proatBgSunken)
                                )
                        }
                        .buttonStyle(.plain)
                        .popover(isPresented: $isShowingEmojiPicker, arrowEdge: .bottom) {
                            EmojiPickerView(
                                selectedEmoji: $selectedEmoji,
                                isPresented: $isShowingEmojiPicker
                            )
                        }

                        TextField("Naam", text: $configName)
                            .textFieldStyle(.roundedBorder)
                            .focused($isNameFieldFocused)
                    }
                }

                Section("Triggerscenario's") {
                    VStack(alignment: .leading, spacing: 10) {
                        HStack {
                            Text("Apps")
                            Spacer()
                            AddIconButton(helpText: "App toevoegen") {
                                loadInstalledApps()
                                isShowingAppPicker = true
                            }
                            .popover(isPresented: $isShowingAppPicker, arrowEdge: .bottom) {
                                AppPickerPopover(
                                    installedApps: filteredApps,
                                    selectedAppConfigs: $selectedAppConfigs,
                                    searchText: $searchText
                                )
                            }
                        }

                        if selectedAppConfigs.isEmpty {
                            Text("Nog geen apps toegevoegd")
                                .foregroundColor(.proatText3)
                                .font(.subheadline)
                        } else {
                            LazyVGrid(columns: [GridItem(.adaptive(minimum: 44, maximum: 50), spacing: 10)], spacing: 10) {
                                ForEach(selectedAppConfigs) { appConfig in
                                    ZStack(alignment: .topTrailing) {
                                        if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: appConfig.bundleIdentifier) {
                                            Image(nsImage: NSWorkspace.shared.icon(forFile: appURL.path))
                                                .resizable()
                                                .aspectRatio(contentMode: .fill)
                                                .frame(width: 44, height: 44)
                                                .clipShape(RoundedRectangle(cornerRadius: 10))
                                        } else {
                                            Image(systemName: "app.fill")
                                                .resizable()
                                                .aspectRatio(contentMode: .fit)
                                                .frame(width: 26, height: 26)
                                                .frame(width: 44, height: 44)
                                                .background(
                                                    RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous)
                                                        .fill(Color.proatBgSunken)
                                                )
                                        }

                                        Button {
                                            selectedAppConfigs.removeAll(where: { $0.id == appConfig.id })
                                        } label: {
                                            Image(systemName: "xmark.circle.fill")
                                                .font(.system(size: 14))
                                                .foregroundColor(.proatText2)
                                        }
                                        .buttonStyle(.plain)
                                        .offset(x: 6, y: -6)
                                    }
                                }
                            }
                            .padding(.vertical, 2)
                        }
                    }
                    .padding(.vertical, 2)

                    VStack(alignment: .leading, spacing: 10) {
                        Text("Websites")

                        HStack {
                            TextField("Website-URL invoeren", text: $newWebsiteURL)
                                .textFieldStyle(.roundedBorder)
                                .onSubmit { addWebsite() }

                            AddIconButton(helpText: "Website toevoegen", isDisabled: newWebsiteURL.isEmpty) {
                                addWebsite()
                            }
                        }

                        if websiteConfigs.isEmpty {
                            Text("Nog geen websites toegevoegd")
                                .foregroundColor(.proatText3)
                                .font(.subheadline)
                        } else {
                            LazyVGrid(columns: [GridItem(.adaptive(minimum: 140, maximum: 220), spacing: 10)], spacing: 10) {
                                ForEach(websiteConfigs) { urlConfig in
                                    HStack(spacing: ProatSpacing.xs - 2) {
                                        Image(systemName: "globe")
                                            .foregroundColor(.proatText2)
                                        Text(urlConfig.url)
                                            .foregroundColor(.proatText1)
                                            .lineLimit(1)
                                        Spacer(minLength: 0)
                                        Button {
                                            websiteConfigs.removeAll(where: { $0.id == urlConfig.id })
                                        } label: {
                                            Image(systemName: "xmark.circle.fill")
                                                .foregroundColor(.proatText2)
                                        }
                                        .buttonStyle(.plain)
                                    }
                                    .padding(.horizontal, ProatSpacing.xs)
                                    .padding(.vertical, ProatSpacing.xs - 2)
                                    .background(
                                        RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous)
                                            .fill(Color.proatBgSunken)
                                    )
                                }
                            }
                            .padding(.vertical, 2)
                        }
                    }
                    .padding(.vertical, 2)
                }

                Section("Transcriptie") {
                    if transcriptionModelManager.usableModels.isEmpty {
                        Text("Geen transcriptiemodellen beschikbaar. Maak verbinding met een cloudservice of download een lokaal model in het tabblad AI-modellen.")
                            .foregroundColor(.secondary)
                    } else {
                        let modelBinding = Binding<String?>(
                            get: { selectedTranscriptionModelName ?? transcriptionModelManager.currentTranscriptionModel?.name },
                            set: { selectedTranscriptionModelName = $0 }
                        )

                        Picker("Model", selection: modelBinding) {
                            ForEach(transcriptionModelManager.usableModels, id: \.name) { model in
                                Text(model.displayName).tag(model.name as String?)
                            }
                        }
                        .onChange(of: selectedTranscriptionModelName) { _, newModelName in
                            if let modelName = newModelName ?? transcriptionModelManager.currentTranscriptionModel?.name,
                               let model = transcriptionModelManager.allAvailableModels.first(where: { $0.name == modelName }) {
                                if model.provider == .fluidAudio || model.provider == .gemini {
                                    selectedLanguage = "auto"
                                } else {
                                    useCompatibleLanguage(for: model)
                                }
                            }
                        }
                    }

                    if languageSelectionDisabled() {
                        LabeledContent("Taal") {
                            Text("Automatisch")
                                .foregroundColor(.secondary)
                        }
                        .onAppear {
                            selectedLanguage = "auto"
                        }
                    } else if let selectedModel = effectiveModelName,
                              let modelInfo = transcriptionModelManager.allAvailableModels.first(where: { $0.name == selectedModel }),
                              modelInfo.isMultilingualModel {
                        let languageBinding = Binding<String?>(
                            get: { selectedLanguage ?? UserDefaults.standard.string(forKey: "SelectedLanguage") ?? "auto" },
                            set: { selectedLanguage = $0 }
                        )

                        Picker("Taal", selection: languageBinding) {
                            ForEach(availableLanguages(for: modelInfo).sorted(by: {
                                if $0.key == "auto" { return true }
                                if $1.key == "auto" { return false }
                                return $0.value < $1.value
                            }), id: \.key) { key, value in
                                Text(value).tag(key as String?)
                            }
                        }
                    } else if let selectedModel = effectiveModelName,
                              let modelInfo = transcriptionModelManager.allAvailableModels.first(where: { $0.name == selectedModel }),
                              !modelInfo.isMultilingualModel {
                        EmptyView()
                            .onAppear {
                                if selectedLanguage == nil {
                                    selectedLanguage = "en"
                                }
                            }
                    }
                    Button {
                        withAnimation(.easeInOut(duration: 0.15)) {
                            isTranscriptFormattingExpanded.toggle()
                        }
                    } label: {
                        HStack {
                            Text("Transcript-opmaak")
                            Spacer()
                            Image(systemName: "chevron.right")
                                .font(.system(size: 11, weight: .semibold))
                                .foregroundColor(.proatText2)
                                .rotationEffect(.degrees(isTranscriptFormattingExpanded ? 90 : 0))
                        }
                        .contentShape(Rectangle())
                    }
                    .buttonStyle(.plain)

                    if isTranscriptFormattingExpanded {
                        VStack(alignment: .leading, spacing: 10) {
                            Toggle(isOn: $isTextFormattingEnabled) {
                                HStack(spacing: 4) {
                                    Text("Alinea's")
                                    InfoTip("Pas intelligente tekstopmaak toe om grote tekstblokken op te splitsen in alinea's.")
                                }
                            }

                            Toggle(isOn: $removePunctuation) {
                                HStack(spacing: 4) {
                                    Text("Leestekens verwijderen")
                                    InfoTip("Verwijder leestekens uit de transcriptie-uitvoer.")
                                }
                            }

                            Toggle(isOn: $lowercaseTranscription) {
                                HStack(spacing: 4) {
                                    Text("Kleine letters")
                                    InfoTip("Zet de transcriptie-uitvoer om naar kleine letters.")
                                }
                            }
                        }
                        .padding(.top, 4)
                    }
                }

                Section("AI-verbetering") {
                    Toggle("AI-verbetering", isOn: $isAIEnhancementEnabled)
                        .onChange(of: isAIEnhancementEnabled) { _, newValue in
                            if newValue {
                                if selectedAIProvider == nil {
                                    selectedAIProvider = aiService.selectedProvider.rawValue
                                }
                                if selectedAIModel == nil {
                                    selectedAIModel = aiService.currentModel
                                }
                                if selectedPromptId == nil {
                                    selectedPromptId = enhancementService.allPrompts.first?.id
                                }
                            }
                        }

                    let providerBinding = Binding<AIProvider>(
                        get: {
                            if let providerName = selectedAIProvider,
                               let provider = AIProvider(rawValue: providerName) {
                                return provider
                            }
                            return aiService.selectedProvider
                        },
                        set: { newValue in
                            selectedAIProvider = newValue.rawValue
                            selectedAIModel = nil
                        }
                    )

                    if isAIEnhancementEnabled {
                        if aiService.connectedProviders.isEmpty {
                            LabeledContent("AI-provider") {
                                Text("Geen providers verbonden")
                                    .foregroundColor(.secondary)
                                    .italic()
                            }
                        } else {
                            Picker("AI-provider", selection: providerBinding) {
                                ForEach(aiService.connectedProviders.filter { $0 != .elevenLabs && $0 != .deepgram }, id: \.self) { provider in
                                    Text(provider.rawValue).tag(provider)
                                }
                            }
                            .onChange(of: selectedAIProvider) { _, newValue in
                                if let provider = newValue.flatMap({ AIProvider(rawValue: $0) }) {
                                    selectedAIModel = provider.defaultModel
                                }
                            }
                        }

                        let providerName = selectedAIProvider ?? aiService.selectedProvider.rawValue
                        if let provider = AIProvider(rawValue: providerName),
                           provider != .custom {
                            let models = aiService.availableModels(for: provider)
                            if models.isEmpty {
                                LabeledContent("AI-model") {
                                    Text(provider == .openRouter ? "Geen modellen geladen" : "Geen modellen beschikbaar")
                                        .foregroundColor(.secondary)
                                        .italic()
                                }
                            } else {
                                let modelBinding = Binding<String>(
                                    get: {
                                        if let model = selectedAIModel, !model.isEmpty { return model }
                                        return aiService.currentModel
                                    },
                                    set: { newModelValue in
                                        selectedAIModel = newModelValue
                                    }
                                )

                                Picker("AI-model", selection: modelBinding) {
                                    ForEach(models, id: \.self) { model in
                                        Text(model).tag(model)
                                    }
                                }

                                if provider == .openRouter {
                                    Button("Modellen vernieuwen") {
                                        Task { await aiService.fetchOpenRouterModels() }
                                    }
                                    .help("Modellen vernieuwen")
                                }
                            }
                        }

                        if enhancementService.allPrompts.isEmpty {
                            LabeledContent("Verfijnings-prompt") {
                                Text("Geen prompts beschikbaar")
                                    .foregroundColor(.secondary)
                            }
                        } else {
                            Picker("Verfijnings-prompt", selection: $selectedPromptId) {
                                ForEach(enhancementService.allPrompts) { prompt in
                                    Text(prompt.title).tag(prompt.id as UUID?)
                                }
                            }
                        }

                        Toggle("Contextbewustzijn", isOn: $useScreenCapture)
                    }
                }

                Section("Geavanceerd") {
                    Toggle(isOn: $isDefault) {
                        HStack(spacing: 6) {
                            Text("Als standaard")
                            InfoTip("De standaard Power Mode wordt gebruikt wanneer geen specifieke app of website overeenkomt.")
                        }
                    }

                    Picker(selection: $autoSendKey) {
                        ForEach(AutoSendKey.allCases, id: \.self) { key in
                            Text(key.displayName).tag(key)
                        }
                    } label: {
                        HStack(spacing: 6) {
                            Text("Automatisch verzenden")
                            InfoTip("Drukt automatisch een toetscombinatie in nadat tekst is geplakt. Handig voor chatapps of formulieren die andere verzendsneltoetsen gebruiken.")
                        }
                    }

                    HStack {
                        Text("Sneltoets")
                        InfoTip("Wijs een unieke sneltoets toe om deze Power Mode direct te activeren en de opname te starten.")

                        Spacer()

                        KeyboardShortcuts.Recorder(for: .powerMode(id: powerModeConfigId))
                            .controlSize(.regular)
                            .frame(minHeight: 28)
                    }
                }
            }
            .formStyle(.grouped)
            .scrollContentBackground(.hidden)
            .background(Color.proatBgBase)
            .confirmationDialog(
                "Power Mode verwijderen?",
                isPresented: $isShowingDeleteConfirmation,
                titleVisibility: .visible
            ) {
                if case .edit(let config) = mode {
                    Button("Verwijderen", role: .destructive) {
                        powerModeManager.removeConfiguration(with: config.id)
                        onDismiss()
                    }
                }
                Button("Annuleren", role: .cancel) { }
            } message: {
                if case .edit(let config) = mode {
                    Text("Weet je zeker dat je de Power Mode '\(config.name)' wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.")
                }
            }
            .powerModeValidationAlert(errors: validationErrors, isPresented: $showValidationAlert)
            .onAppear {
                // Set AI provider/model after EnvironmentObjects are available
                if case .add = mode {
                    if selectedAIProvider == nil {
                        selectedAIProvider = aiService.selectedProvider.rawValue
                    }
                    if selectedAIModel == nil || selectedAIModel?.isEmpty == true {
                        selectedAIModel = aiService.currentModel
                    }
                }

                if isAIEnhancementEnabled && selectedPromptId == nil {
                    selectedPromptId = enhancementService.allPrompts.first?.id
                }

                if let selectedModelName = effectiveModelName,
                   let model = transcriptionModelManager.allAvailableModels.first(where: { $0.name == selectedModelName }),
                   model.provider != .fluidAudio,
                   model.provider != .gemini {
                    useCompatibleLanguage(for: model)
                }

                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    isNameFieldFocused = true
                }
            }

            // Footer
            VStack(spacing: 0) {
                HStack {
                    if case .edit = mode {
                        Button("Verwijderen", role: .destructive) {
                            isShowingDeleteConfirmation = true
                        }
                        .buttonStyle(.bordered)
                    } else {
                        Button("Annuleren") { onDismiss() }
                            .keyboardShortcut(.escape, modifiers: [])
                            .buttonStyle(.plain)
                            .foregroundColor(.proatText2)
                    }

                    Spacer()

                    Button {
                        saveConfiguration()
                    } label: {
                        Text("Wijzigingen opslaan")
                            .font(.system(size: 13, weight: .semibold))
                            .foregroundColor(.white)
                            .frame(minWidth: 100)
                            .padding(.horizontal, ProatSpacing.s)
                            .padding(.vertical, ProatSpacing.xs - 2)
                            .background(
                                Capsule().fill(canSave
                                                ? AnyShapeStyle(LinearGradient.proatTeal)
                                                : AnyShapeStyle(Color.proatText3))
                            )
                            .proatShadowRust()
                    }
                    .buttonStyle(.plain)
                    .disabled(!canSave)
                    .keyboardShortcut(.return, modifiers: .command)
                }
                .padding(.horizontal, ProatSpacing.l - 4)
                .padding(.vertical, ProatSpacing.m)
                .background(Color.proatBgRaised)
            }
        }
    }

    // MARK: - Actions

    private func addWebsite() {
        guard !newWebsiteURL.isEmpty else { return }
        let cleanedURL = powerModeManager.cleanURL(newWebsiteURL)
        websiteConfigs.append(URLConfig(url: cleanedURL))
        newWebsiteURL = ""
    }

    private func getConfigForForm() -> PowerModeConfig {
        let shortcut = KeyboardShortcuts.getShortcut(for: .powerMode(id: powerModeConfigId))
        let hotkeyString = shortcut != nil ? "configured" : nil

        switch mode {
        case .add:
            return PowerModeConfig(
                id: powerModeConfigId,
                name: configName,
                emoji: selectedEmoji,
                appConfigs: selectedAppConfigs.isEmpty ? nil : selectedAppConfigs,
                urlConfigs: websiteConfigs.isEmpty ? nil : websiteConfigs,
                isAIEnhancementEnabled: isAIEnhancementEnabled,
                selectedPrompt: selectedPromptId?.uuidString,
                selectedTranscriptionModelName: selectedTranscriptionModelName,
                selectedLanguage: selectedLanguage,
                useScreenCapture: useScreenCapture,
                isTextFormattingEnabled: isTextFormattingEnabled,
                removePunctuation: removePunctuation,
                lowercaseTranscription: lowercaseTranscription,
                selectedAIProvider: selectedAIProvider,
                selectedAIModel: selectedAIModel,
                autoSendKey: autoSendKey,
                isDefault: isDefault,
                hotkeyShortcut: hotkeyString
            )
        case .edit(let config):
            var updatedConfig = config
            updatedConfig.name = configName
            updatedConfig.emoji = selectedEmoji
            updatedConfig.isAIEnhancementEnabled = isAIEnhancementEnabled
            updatedConfig.selectedPrompt = selectedPromptId?.uuidString
            updatedConfig.selectedTranscriptionModelName = selectedTranscriptionModelName
            updatedConfig.selectedLanguage = selectedLanguage
            updatedConfig.isTextFormattingEnabled = isTextFormattingEnabled
            updatedConfig.removePunctuation = removePunctuation
            updatedConfig.lowercaseTranscription = lowercaseTranscription
            updatedConfig.appConfigs = selectedAppConfigs.isEmpty ? nil : selectedAppConfigs
            updatedConfig.urlConfigs = websiteConfigs.isEmpty ? nil : websiteConfigs
            updatedConfig.useScreenCapture = useScreenCapture
            updatedConfig.autoSendKey = autoSendKey
            updatedConfig.selectedAIProvider = selectedAIProvider
            updatedConfig.selectedAIModel = selectedAIModel
            updatedConfig.isDefault = isDefault
            updatedConfig.hotkeyShortcut = hotkeyString
            return updatedConfig
        }
    }

    private func loadInstalledApps() {
        let userAppURLs = FileManager.default.urls(for: .applicationDirectory, in: .userDomainMask)
        let localAppURLs = FileManager.default.urls(for: .applicationDirectory, in: .localDomainMask)
        let systemAppURLs = FileManager.default.urls(for: .applicationDirectory, in: .systemDomainMask)
        let allAppURLs = userAppURLs + localAppURLs + systemAppURLs

        var allApps: [URL] = []

        func scanDirectory(_ baseURL: URL, depth: Int = 0) {
            // Prevent infinite recursion from circular symlinks
            guard depth < 5 else { return }
            guard let enumerator = FileManager.default.enumerator(
                at: baseURL,
                includingPropertiesForKeys: [.isApplicationKey, .isDirectoryKey, .isSymbolicLinkKey],
                options: [.skipsHiddenFiles]
            ) else { return }

            for item in enumerator {
                guard let url = item as? URL else { continue }
                let resolvedURL = url.resolvingSymlinksInPath()

                if resolvedURL.pathExtension == "app" {
                    allApps.append(resolvedURL)
                    enumerator.skipDescendants()
                    continue
                }

                // Traverse symlinked directories manually
                var isDirectory: ObjCBool = false
                if url != resolvedURL &&
                   FileManager.default.fileExists(atPath: resolvedURL.path, isDirectory: &isDirectory) &&
                   isDirectory.boolValue {
                    enumerator.skipDescendants()
                    scanDirectory(resolvedURL, depth: depth + 1)
                }
            }
        }

        for baseURL in allAppURLs {
            scanDirectory(baseURL)
        }

        installedApps = allApps.compactMap { url in
            guard let bundle = Bundle(url: url),
                  let bundleId = bundle.bundleIdentifier,
                  let name = (bundle.infoDictionary?["CFBundleName"] as? String) ??
                            (bundle.infoDictionary?["CFBundleDisplayName"] as? String) else {
                return nil
            }
            let icon = NSWorkspace.shared.icon(forFile: url.path)
            return (url: url, name: name, bundleId: bundleId, icon: icon)
        }
        .sorted { $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending }
    }

    private func saveConfiguration() {
        let config = getConfigForForm()
        let validator = PowerModeValidator(powerModeManager: powerModeManager)
        validationErrors = validator.validateForSave(config: config, mode: mode)

        if !validationErrors.isEmpty {
            showValidationAlert = true
            return
        }

        if isDefault {
            powerModeManager.setAsDefault(configId: config.id, skipSave: true)
        }

        switch mode {
        case .add:
            powerModeManager.addConfiguration(config)
        case .edit:
            powerModeManager.updateConfiguration(config)
        }

        onDismiss()
    }
}
