import SwiftUI
import Combine
import AppKit

struct FluidAudioModelCardView: View {
    let model: FluidAudioModel
    @ObservedObject var fluidAudioModelManager: FluidAudioModelManager
    @ObservedObject var transcriptionModelManager: TranscriptionModelManager
    @State private var streamingEnabled: Bool

    init(model: FluidAudioModel, fluidAudioModelManager: FluidAudioModelManager, transcriptionModelManager: TranscriptionModelManager) {
        self.model = model
        _fluidAudioModelManager = ObservedObject(wrappedValue: fluidAudioModelManager)
        _transcriptionModelManager = ObservedObject(wrappedValue: transcriptionModelManager)
        let key = "streaming-enabled-\(model.name)"
        _streamingEnabled = State(initialValue: UserDefaults.standard.object(forKey: key) as? Bool ?? true)
    }

    private var streamingDefaultsKey: String {
        "streaming-enabled-\(model.name)"
    }

    var isCurrent: Bool {
        transcriptionModelManager.currentTranscriptionModel?.name == model.name
    }

    var isDownloaded: Bool {
        fluidAudioModelManager.isFluidAudioModelDownloaded(model)
    }

    var isDownloading: Bool {
        fluidAudioModelManager.isFluidAudioModelDownloading(model)
    }

    var body: some View {
        HStack(alignment: .top, spacing: ProatSpacing.m) {
            VStack(alignment: .leading, spacing: ProatSpacing.xs - 2) {
                headerSection
                metadataSection
                descriptionSection
                progressSection
            }
            .frame(maxWidth: .infinity, alignment: .leading)

            actionSection
        }
        .padding(ProatSpacing.m)
        .background(ProatModelCardBackground(isSelected: isCurrent))
    }

    private var headerSection: some View {
        HStack(alignment: .firstTextBaseline) {
            Text(model.displayName)
                .font(ProatFont.sectie)
                .foregroundColor(.proatText1)

            if model.supportsStreaming && isDownloaded {
                Toggle("Realtime", isOn: $streamingEnabled)
                    .toggleStyle(.switch)
                    .controlSize(.mini)
                    .font(.system(size: 11, weight: .medium))
                    .foregroundColor(.proatText2)
                    .onChange(of: streamingEnabled) { _, newValue in
                        UserDefaults.standard.set(newValue, forKey: streamingDefaultsKey)
                    }
                    .help(streamingEnabled ? "Live streaming ingeschakeld — klik om naar batch te wisselen" : "Batchmodus — klik om live streaming in te schakelen")
            }

            Spacer()
        }
    }

    private var metadataSection: some View {
        HStack(spacing: ProatSpacing.s) {
            Label(model.language, systemImage: "globe")
            Label(model.size, systemImage: "internaldrive")
            HStack(spacing: 3) {
                Text("Snelheid")
                progressDotsWithNumber(value: model.speed * 10)
            }
            .fixedSize(horizontal: true, vertical: false)
            HStack(spacing: 3) {
                Text("Nauwkeurigheid")
                progressDotsWithNumber(value: model.accuracy * 10)
            }
            .fixedSize(horizontal: true, vertical: false)
        }
        .font(ProatFont.klein)
        .foregroundColor(.proatText2)
        .lineLimit(1)
    }

    private var descriptionSection: some View {
        Text(model.description)
            .font(ProatFont.klein)
            .foregroundColor(.proatText3)
            .lineLimit(2)
            .fixedSize(horizontal: false, vertical: true)
            .padding(.top, ProatSpacing.xs / 2)
    }

    private var progressSection: some View {
        Group {
            if let status = fluidAudioModelManager.downloadStatus(for: model) {
                VStack(alignment: .leading, spacing: ProatSpacing.xs - 2) {
                    HStack {
                        Text(status.message)
                            .lineLimit(1)

                        Spacer()

                        Text("\(Int(status.fractionCompleted * 100))%")
                            .fontDesign(.monospaced)
                    }
                    .font(.system(size: 12, weight: .medium))
                    .foregroundColor(.proatText2)

                    ProgressView(value: status.fractionCompleted)
                        .progressViewStyle(LinearProgressViewStyle())
                        .tint(.proatTeal)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding(.top, ProatSpacing.xs)
                .animation(.smooth, value: status.fractionCompleted)
            }
        }
    }

    private var actionSection: some View {
        HStack(spacing: ProatSpacing.xs) {
            if isCurrent {
                Text("Standaardmodel")
                    .font(.system(size: 12, weight: .medium))
                    .foregroundColor(.proatTeal)
            } else if isDownloaded {
                Button(action: {
                    Task {
                        transcriptionModelManager.setDefaultTranscriptionModel(model)
                    }
                }) {
                    Text("Als standaard instellen")
                        .font(.system(size: 12))
                }
                .buttonStyle(.bordered)
                .controlSize(.small)
            } else {
                Button(action: {
                    Task {
                        await fluidAudioModelManager.downloadFluidAudioModel(model)
                    }
                }) {
                    ProatPrimaryPillLabel(
                        title: isDownloading ? "Downloaden…" : "Downloaden",
                        systemImage: "arrow.down.circle"
                    )
                }
                .buttonStyle(.plain)
                .disabled(isDownloading)
            }

            if isDownloaded {
                Menu {
                    Button(action: {
                        fluidAudioModelManager.deleteFluidAudioModel(model)
                    }) {
                        Label("Model verwijderen", systemImage: "trash")
                    }

                    Button {
                        fluidAudioModelManager.showFluidAudioModelInFinder(model)
                    } label: {
                        Label("Toon in Finder", systemImage: "folder")
                    }

                } label: {
                    Image(systemName: "ellipsis.circle")
                        .font(.system(size: 14))
                        .foregroundColor(.proatText2)
                }
                .menuStyle(.borderlessButton)
                .menuIndicator(.hidden)
                .frame(width: 20, height: 20)
            }
        }
    }
}
