import SwiftUI
import SwiftData
import AppKit
import UniformTypeIdentifiers

enum ModelFilter: String, CaseIterable, Identifiable {
    case recommended = "Aanbevolen"
    case local = "Lokaal"
    case cloud = "Cloud"
    case custom = "Eigen"
    var id: String { self.rawValue }
}

struct ModelManagementView: View {
    @EnvironmentObject private var whisperModelManager: WhisperModelManager
    @EnvironmentObject private var fluidAudioModelManager: FluidAudioModelManager
    @EnvironmentObject private var transcriptionModelManager: TranscriptionModelManager
    @State private var customModelToEdit: CustomCloudModel?
    @StateObject private var aiService = AIService()
    @StateObject private var customModelManager = CustomCloudModelManager.shared
    @EnvironmentObject private var enhancementService: AIEnhancementService
    @Environment(\.modelContext) private var modelContext
    @StateObject private var whisperPrompt = WhisperPrompt()
    @ObservedObject private var warmupCoordinator = WhisperModelWarmupCoordinator.shared

    @State private var selectedFilter: ModelFilter = .recommended
    @State private var isShowingSettings = false

    private let settingsPanelWidth: CGFloat = 400

    // State for the unified alert
    @State private var isShowingDeleteAlert = false
    @State private var alertTitle = ""
    @State private var alertMessage = ""
    @State private var deleteActionClosure: () -> Void = {}

    private func closeSettings() {
        withAnimation(.smooth(duration: 0.3)) {
            isShowingSettings = false
        }
    }

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: ProatSpacing.l) {
                if SystemArchitecture.isIntelMac {
                    intelMacWarningBanner
                }

                defaultModelSection
                languageSelectionSection
                availableModelsSection
            }
            .padding(ProatSpacing.xl + ProatSpacing.xs)
        }
        .frame(minWidth: 600, minHeight: 500)
        .background(Color.proatBgBase)
        .slidingPanel(isPresented: $isShowingSettings, width: settingsPanelWidth) {
            settingsPanelContent
        }
        .alert(isPresented: $isShowingDeleteAlert) {
            Alert(
                title: Text(alertTitle),
                message: Text(alertMessage),
                primaryButton: .destructive(Text("Verwijderen"), action: deleteActionClosure),
                secondaryButton: .cancel()
            )
        }
    }

    private var settingsPanelContent: some View {
        VStack(spacing: 0) {
            // Header
            HStack(spacing: ProatSpacing.s) {
                Text("Modelinstellingen")
                    .font(ProatFont.sectie)
                    .foregroundColor(.proatText1)

                Spacer()

                Button(action: { closeSettings() }) {
                    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
            )

            // Content
            ModelSettingsView(whisperPrompt: whisperPrompt)
        }
    }
    
    private var defaultModelSection: some View {
        VStack(alignment: .leading, spacing: ProatSpacing.xs) {
            Text("Standaardmodel")
                .font(ProatFont.klein)
                .foregroundColor(.proatText2)
                .textCase(.uppercase)
            Text(transcriptionModelManager.currentTranscriptionModel?.displayName ?? "Geen model geselecteerd")
                .font(ProatFont.titel)
                .foregroundColor(.proatText1)
        }
        .frame(maxWidth: .infinity, alignment: .leading)
        .proatCard()
    }

    private var languageSelectionSection: some View {
        LanguageSelectionView(transcriptionModelManager: transcriptionModelManager, displayMode: .full, whisperPrompt: whisperPrompt)
    }
    
    private var availableModelsSection: some View {
        VStack(alignment: .leading, spacing: ProatSpacing.m) {
            HStack {
                // Modern compact pill switcher
                HStack(spacing: ProatSpacing.xs) {
                    ForEach(ModelFilter.allCases, id: \.self) { filter in
                        Button(action: {
                            withAnimation(.spring(response: 0.3, dampingFraction: 0.8)) {
                                selectedFilter = filter
                                isShowingSettings = false
                            }
                        }) {
                            Text(filter.rawValue)
                                .font(.system(size: 13, weight: selectedFilter == filter ? .semibold : .medium))
                                .foregroundColor(selectedFilter == filter ? .proatTeal : .proatText2)
                                .padding(.horizontal, ProatSpacing.m)
                                .padding(.vertical, ProatSpacing.xs)
                                .background(
                                    Capsule()
                                        .fill(selectedFilter == filter ? Color.proatTealTint : Color.proatBgRaised)
                                        .overlay(
                                            Capsule()
                                                .stroke(selectedFilter == filter ? Color.proatTeal : Color.proatBorder,
                                                        lineWidth: 1)
                                        )
                                )
                        }
                        .buttonStyle(PlainButtonStyle())
                    }
                }

                Spacer()

                Button(action: {
                    withAnimation(.smooth(duration: 0.3)) {
                        isShowingSettings.toggle()
                    }
                }) {
                    Image(systemName: "gear")
                        .font(.system(size: 16, weight: .medium))
                        .foregroundColor(isShowingSettings ? .proatTeal : .proatText2)
                        .padding(ProatSpacing.s)
                        .background(
                            Circle()
                                .fill(isShowingSettings ? Color.proatTealTint : Color.proatBgRaised)
                                .overlay(
                                    Circle()
                                        .stroke(isShowingSettings ? Color.proatTeal : Color.proatBorder,
                                                lineWidth: 1)
                                )
                        )
                }
                .buttonStyle(PlainButtonStyle())
            }
            .padding(.bottom, ProatSpacing.s)

            VStack(spacing: ProatSpacing.s) {
                    ForEach(filteredModels, id: \.id) { model in
                        let isWarming = (model as? WhisperModel).map { whisperModel in
                            warmupCoordinator.isWarming(modelNamed: whisperModel.name)
                        } ?? false

                        ModelCardView(
                            model: model,
                            fluidAudioModelManager: fluidAudioModelManager,
                            transcriptionModelManager: transcriptionModelManager,
                            isDownloaded: whisperModelManager.availableModels.contains { $0.name == model.name },
                            isCurrent: transcriptionModelManager.currentTranscriptionModel?.name == model.name,
                            downloadProgress: whisperModelManager.downloadProgress,
                            modelURL: whisperModelManager.availableModels.first { $0.name == model.name }?.url,
                            isWarming: isWarming,
                            deleteAction: {
                                if let customModel = model as? CustomCloudModel {
                                    alertTitle = "Eigen model verwijderen"
                                    alertMessage = "Weet je zeker dat je het eigen model '\(customModel.displayName)' wilt verwijderen?"
                                    deleteActionClosure = {
                                        customModelManager.removeCustomModel(withId: customModel.id)
                                        transcriptionModelManager.refreshAllAvailableModels()
                                    }
                                    isShowingDeleteAlert = true
                                } else if let downloadedModel = whisperModelManager.availableModels.first(where: { $0.name == model.name }) {
                                    alertTitle = "Model verwijderen"
                                    alertMessage = "Weet je zeker dat je het model '\(downloadedModel.name)' wilt verwijderen?"
                                    deleteActionClosure = {
                                        Task {
                                            await whisperModelManager.deleteModel(downloadedModel)
                                        }
                                    }
                                    isShowingDeleteAlert = true
                                }
                            },
                            setDefaultAction: {
                                Task {
                                    transcriptionModelManager.setDefaultTranscriptionModel(model)
                                }
                            },
                            downloadAction: {
                                if let whisperModel = model as? WhisperModel {
                                    Task { await whisperModelManager.downloadModel(whisperModel) }
                                }
                            },
                            editAction: model.provider == .custom ? { customModel in
                                customModelToEdit = customModel
                            } : nil
                        )
                    }
                    
                    // Import button as a card at the end of the Local list
                    if selectedFilter == .local {
                        HStack(spacing: ProatSpacing.xs) {
                            Button(action: { presentImportPanel() }) {
                                HStack(spacing: ProatSpacing.xs) {
                                    Image(systemName: "square.and.arrow.down")
                                    Text("Lokaal model importeren…")
                                        .font(.system(size: 12, weight: .semibold))
                                }
                                .foregroundColor(.proatText1)
                                .frame(maxWidth: .infinity)
                                .padding(ProatSpacing.m)
                                .background(
                                    RoundedRectangle(cornerRadius: ProatRadius.kaart, style: .continuous)
                                        .fill(Color.proatBgRaised)
                                        .overlay(
                                            RoundedRectangle(cornerRadius: ProatRadius.kaart, style: .continuous)
                                                .strokeBorder(style: StrokeStyle(lineWidth: 1, dash: [4, 4]))
                                                .foregroundColor(.proatBorder)
                                        )
                                )
                            }
                            .buttonStyle(.plain)

                            InfoTip(
                                "Voeg een eigen fijn afgestemd whisper-model toe om met Proat te gebruiken. Selecteer het gedownloade .bin-bestand."
                            )
                            .help("Meer over eigen lokale modellen")
                        }
                    }

                    if selectedFilter == .custom {
                        HStack(spacing: ProatSpacing.xs - 2) {
                            Image(systemName: "info.circle")
                                .font(.system(size: 12))
                            Text("Alleen OpenAI-compatibele transcriptie-API's worden ondersteund.")
                                .font(ProatFont.klein)
                        }
                        .foregroundColor(.proatText2)
                        .padding(.bottom, ProatSpacing.xs / 2)

                        AddCustomModelCardView(
                            customModelManager: customModelManager,
                            editingModel: customModelToEdit
                        ) {
                            // Refresh the models when a new custom model is added
                            transcriptionModelManager.refreshAllAvailableModels()
                            customModelToEdit = nil // Clear editing state
                        }
                    }
                }
            }
        .padding()
    }



    private var intelMacWarningBanner: some View {
        HStack(spacing: ProatSpacing.xs + 2) {
            Image(systemName: "exclamationmark.triangle.fill")
                .font(.system(size: 14, weight: .semibold))
                .foregroundColor(.proatWarn)

            Text("Lokale modellen werken niet betrouwbaar op Intel-Macs")
                .font(.system(size: 13, weight: .medium))
                .foregroundColor(.proatText1)

            Spacer()

            Button(action: {
                withAnimation(.spring(response: 0.3, dampingFraction: 0.8)) {
                    selectedFilter = .cloud
                }
            }) {
                HStack(spacing: ProatSpacing.xs / 2) {
                    Text("Cloud gebruiken")
                        .font(.system(size: 12, weight: .semibold))
                    Image(systemName: "arrow.right")
                        .font(.system(size: 10, weight: .bold))
                }
                .foregroundColor(.proatWarn)
                .padding(.horizontal, ProatSpacing.s)
                .padding(.vertical, ProatSpacing.xs - 2)
                .background(Color.proatWarn.opacity(0.12))
                .clipShape(Capsule())
            }
            .buttonStyle(.plain)
        }
        .padding(.horizontal, ProatSpacing.m - 2)
        .padding(.vertical, ProatSpacing.xs + 2)
        .background(Color.proatWarn.opacity(0.08))
        .clipShape(RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous))
    }

    private var filteredModels: [any TranscriptionModel] {
        switch selectedFilter {
        case .recommended:
            return transcriptionModelManager.allAvailableModels.filter {
                let recommendedNames = ["ggml-base.en", "parakeet-tdt-0.6b-v2", "ggml-large-v3-turbo-q5_0", "whisper-large-v3-turbo"]
                return recommendedNames.contains($0.name)
            }.sorted { model1, model2 in
                let recommendedOrder = ["ggml-base.en", "parakeet-tdt-0.6b-v2", "ggml-large-v3-turbo-q5_0", "whisper-large-v3-turbo"]
                let index1 = recommendedOrder.firstIndex(of: model1.name) ?? Int.max
                let index2 = recommendedOrder.firstIndex(of: model2.name) ?? Int.max
                return index1 < index2
            }
        case .local:
            return transcriptionModelManager.allAvailableModels.filter {
                ($0.provider == .whisper || $0.provider == .nativeApple || $0.provider == .fluidAudio)
                    && transcriptionModelManager.isAvailableOnCurrentOS($0)
            }
        case .cloud:
            return transcriptionModelManager.allAvailableModels.filter { CloudProviderRegistry.provider(for: $0.provider) != nil }
        case .custom:
            return transcriptionModelManager.allAvailableModels.filter { $0.provider == .custom }
        }
    }

    // MARK: - Import Panel
    private func presentImportPanel() {
        let panel = NSOpenPanel()
        panel.allowedContentTypes = [.init(filenameExtension: "bin")!]
        panel.allowsMultipleSelection = false
        panel.canChooseDirectories = false
        panel.resolvesAliases = true
        panel.title = "Selecteer een Whisper ggml .bin-model"
        if panel.runModal() == .OK, let url = panel.url {
            Task { @MainActor in
                await whisperModelManager.importWhisperModel(from: url)
            }
        }
    }
}
