import SwiftUI
import SwiftData

enum SortMode: String {
    case originalAsc = "originalAsc"
    case originalDesc = "originalDesc"
    case replacementAsc = "replacementAsc"
    case replacementDesc = "replacementDesc"
}

enum SortColumn {
    case original
    case replacement
}

struct WordReplacementView: View {
    @Query private var wordReplacements: [WordReplacement]
    @Environment(\.modelContext) private var modelContext
    @State private var showAlert = false
    @State private var editingReplacement: WordReplacement? = nil
    @State private var alertMessage = ""
    @State private var sortMode: SortMode = .originalAsc
    @State private var originalWord = ""
    @State private var replacementWord = ""
    @State private var showInfoPopover = false

    init() {
        if let savedSort = UserDefaults.standard.string(forKey: "wordReplacementSortMode"),
           let mode = SortMode(rawValue: savedSort) {
            _sortMode = State(initialValue: mode)
        }
    }

    private var sortedReplacements: [WordReplacement] {
        switch sortMode {
        case .originalAsc:
            return wordReplacements.sorted { $0.originalText.localizedCaseInsensitiveCompare($1.originalText) == .orderedAscending }
        case .originalDesc:
            return wordReplacements.sorted { $0.originalText.localizedCaseInsensitiveCompare($1.originalText) == .orderedDescending }
        case .replacementAsc:
            return wordReplacements.sorted { $0.replacementText.localizedCaseInsensitiveCompare($1.replacementText) == .orderedAscending }
        case .replacementDesc:
            return wordReplacements.sorted { $0.replacementText.localizedCaseInsensitiveCompare($1.replacementText) == .orderedDescending }
        }
    }
    
    private func toggleSort(for column: SortColumn) {
        switch column {
        case .original:
            sortMode = (sortMode == .originalAsc) ? .originalDesc : .originalAsc
        case .replacement:
            sortMode = (sortMode == .replacementAsc) ? .replacementDesc : .replacementAsc
        }
        UserDefaults.standard.set(sortMode.rawValue, forKey: "wordReplacementSortMode")
    }

    private var shouldShowAddButton: Bool {
        !originalWord.isEmpty || !replacementWord.isEmpty
    }
    
    var body: some View {
        VStack(alignment: .leading, spacing: ProatSpacing.l) {
            HStack(alignment: .top, spacing: ProatSpacing.s) {
                Button(action: { showInfoPopover.toggle() }) {
                    Image(systemName: "info.circle.fill")
                        .foregroundColor(.proatTeal)
                        .font(.system(size: 14))
                }
                .buttonStyle(.plain)
                .popover(isPresented: $showInfoPopover) {
                    WordReplacementInfoPopover()
                }
                Text("Stel vervangingen in om bepaalde woorden of zinnen automatisch te vervangen")
                    .font(ProatFont.klein)
                    .foregroundColor(.proatText2)
                    .fixedSize(horizontal: false, vertical: true)
                Spacer(minLength: 0)
            }
            .proatCard(padding: ProatSpacing.s)

            HStack(spacing: ProatSpacing.xs) {
                TextField("Originele tekst (gebruik komma's voor meerdere)", text: $originalWord)
                    .textFieldStyle(.roundedBorder)
                    .font(ProatFont.mono)

                Image(systemName: "arrow.right")
                    .foregroundColor(.proatText3)
                    .font(.system(size: 10))
                    .frame(width: 10)

                TextField("Vervangende tekst", text: $replacementWord)
                    .textFieldStyle(.roundedBorder)
                    .font(ProatFont.mono)
                    .onSubmit { addReplacement() }

                if shouldShowAddButton {
                    Button(action: addReplacement) {
                        Image(systemName: "plus.circle.fill")
                            .symbolRenderingMode(.hierarchical)
                            .foregroundStyle(Color.proatTeal)
                            .font(.system(size: 16, weight: .semibold))
                    }
                    .buttonStyle(.borderless)
                    .disabled(originalWord.isEmpty || replacementWord.isEmpty)
                    .help("Vervanging toevoegen")
                }
            }
            .animation(.easeInOut(duration: 0.2), value: shouldShowAddButton)

            if !wordReplacements.isEmpty {
                VStack(spacing: 0) {
                    HStack(spacing: ProatSpacing.xs) {
                        Button(action: { toggleSort(for: .original) }) {
                            HStack(spacing: 4) {
                                Text("Origineel")
                                    .font(.system(size: 12, weight: .medium))
                                    .foregroundColor(.proatText2)

                                if sortMode == .originalAsc || sortMode == .originalDesc {
                                    Image(systemName: sortMode == .originalAsc ? "chevron.up" : "chevron.down")
                                        .font(ProatFont.klein)
                                        .foregroundColor(.proatTeal)
                                }
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                        }
                        .buttonStyle(.plain)
                        .help("Sorteren op origineel")

                        Image(systemName: "arrow.right")
                            .foregroundColor(.proatText3)
                            .font(.system(size: 10))
                            .frame(width: 10)

                        Button(action: { toggleSort(for: .replacement) }) {
                            HStack(spacing: 4) {
                                Text("Vervanging")
                                    .font(.system(size: 12, weight: .medium))
                                    .foregroundColor(.proatText2)

                                if sortMode == .replacementAsc || sortMode == .replacementDesc {
                                    Image(systemName: sortMode == .replacementAsc ? "chevron.up" : "chevron.down")
                                        .font(ProatFont.klein)
                                        .foregroundColor(.proatTeal)
                                }
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                        }
                        .buttonStyle(.plain)
                        .help("Sorteren op vervanging")
                    }
                    .padding(.horizontal, ProatSpacing.s)
                    .padding(.vertical, ProatSpacing.xs)

                    Divider().overlay(Color.proatBorder)

                    ScrollView {
                        LazyVStack(spacing: 0) {
                            ForEach(sortedReplacements) { replacement in
                                ReplacementRow(
                                    original: replacement.originalText,
                                    replacement: replacement.replacementText,
                                    onDelete: { removeReplacement(replacement) },
                                    onEdit: { editingReplacement = replacement }
                                )

                                if replacement.id != sortedReplacements.last?.id {
                                    Divider().overlay(Color.proatBorder)
                                }
                            }
                        }
                    }
                    .frame(maxHeight: 300)
                }
                .background(Color.proatBgRaised)
                .clipShape(RoundedRectangle(cornerRadius: ProatRadius.kaart, style: .continuous))
                .overlay(
                    RoundedRectangle(cornerRadius: ProatRadius.kaart, style: .continuous)
                        .stroke(Color.proatBorder, lineWidth: 1)
                )
                .proatShadowKaart()
                .padding(.top, 4)
            }
        }
        .padding()
        .sheet(item: $editingReplacement) { replacement in
            EditReplacementSheet(replacement: replacement, modelContext: modelContext)
        }
        .alert("Vervanging", isPresented: $showAlert) {
            Button("OK", role: .cancel) {}
        } message: {
            Text(alertMessage)
        }
    }

    private func addReplacement() {
        let original = originalWord.trimmingCharacters(in: .whitespacesAndNewlines)
        let replacement = replacementWord.trimmingCharacters(in: .whitespacesAndNewlines)
        if let error = DictionaryService.addWordReplacement(original: original, replacement: replacement, existing: Array(wordReplacements), context: modelContext) {
            alertMessage = error
            showAlert = true
            return
        }
        originalWord = ""
        replacementWord = ""
    }

    private func removeReplacement(_ replacement: WordReplacement) {
        modelContext.delete(replacement)

        do {
            try modelContext.save()
        } catch {
            // Rollback the delete to restore UI consistency
            modelContext.rollback()
            alertMessage = "Kon vervanging niet verwijderen: \(error.localizedDescription)"
            showAlert = true
        }
    }
}

struct WordReplacementInfoPopover: View {
    var body: some View {
        VStack(alignment: .leading, spacing: ProatSpacing.m) {
            Text("Vervangingen gebruiken")
                .font(ProatFont.sectie)
                .foregroundColor(.proatText1)

            VStack(alignment: .leading, spacing: ProatSpacing.xs) {
                Text("Scheid meerdere originelen met komma's:")
                    .font(ProatFont.body)
                    .foregroundColor(.proatText2)

                Text("Voicing, Voice ink, Voiceing")
                    .font(ProatFont.mono)
                    .foregroundColor(.proatText1)
                    .padding(ProatSpacing.xs)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .background(Color.proatBgSunken)
                    .clipShape(RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous))
            }

            Divider().overlay(Color.proatBorder)

            Text("Voorbeelden")
                .font(ProatFont.body)
                .foregroundColor(.proatText2)

            VStack(spacing: ProatSpacing.s) {
                HStack(spacing: ProatSpacing.xs) {
                    VStack(alignment: .leading, spacing: 4) {
                        Text("Origineel:")
                            .font(ProatFont.klein)
                            .foregroundColor(.proatText3)
                        Text("my website link")
                            .font(ProatFont.mono)
                            .foregroundColor(.proatText1)
                    }

                    Image(systemName: "arrow.right")
                        .font(ProatFont.klein)
                        .foregroundColor(.proatText3)

                    VStack(alignment: .leading, spacing: 4) {
                        Text("Vervanging:")
                            .font(ProatFont.klein)
                            .foregroundColor(.proatText3)
                        Text("https://voorbeeld.nl")
                            .font(ProatFont.mono)
                            .foregroundColor(.proatText1)
                    }
                }
                .padding(ProatSpacing.s)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(Color.proatBgSunken)
                .clipShape(RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous))

                HStack(spacing: ProatSpacing.xs) {
                    VStack(alignment: .leading, spacing: 4) {
                        Text("Origineel:")
                            .font(ProatFont.klein)
                            .foregroundColor(.proatText3)
                        Text("Voicing, Voice ink")
                            .font(ProatFont.mono)
                            .foregroundColor(.proatText1)
                    }

                    Image(systemName: "arrow.right")
                        .font(ProatFont.klein)
                        .foregroundColor(.proatText3)

                    VStack(alignment: .leading, spacing: 4) {
                        Text("Vervanging:")
                            .font(ProatFont.klein)
                            .foregroundColor(.proatText3)
                        Text("Proat")
                            .font(ProatFont.mono)
                            .foregroundColor(.proatText1)
                    }
                }
                .padding(ProatSpacing.s)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(Color.proatBgSunken)
                .clipShape(RoundedRectangle(cornerRadius: ProatRadius.knop, style: .continuous))
            }
        }
        .padding(ProatSpacing.m)
        .frame(width: 380)
    }
}

struct ReplacementRow: View {
    let original: String
    let replacement: String
    let onDelete: () -> Void
    let onEdit: () -> Void
    @State private var isEditHovered = false
    @State private var isDeleteHovered = false

    var body: some View {
        HStack(spacing: ProatSpacing.xs) {
            Text(original)
                .font(ProatFont.mono)
                .lineLimit(2)
                .foregroundColor(.proatText1)
                .frame(maxWidth: .infinity, alignment: .leading)

            Image(systemName: "arrow.right")
                .foregroundColor(.proatText3)
                .font(.system(size: 10))
                .frame(width: 10)

            ZStack(alignment: .trailing) {
                Text(replacement)
                    .font(ProatFont.mono)
                    .lineLimit(2)
                    .foregroundColor(.proatText1)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.trailing, 50)

                HStack(spacing: 6) {
                    Button(action: onEdit) {
                        Image(systemName: "pencil.circle.fill")
                            .symbolRenderingMode(.hierarchical)
                            .foregroundColor(isEditHovered ? .proatTeal : .proatText3)
                            .contentTransition(.symbolEffect(.replace))
                    }
                    .buttonStyle(.borderless)
                    .help("Vervanging bewerken")
                    .onHover { hover in
                        withAnimation(.easeInOut(duration: 0.2)) {
                            isEditHovered = hover
                        }
                    }

                    Button(action: onDelete) {
                        Image(systemName: "xmark.circle.fill")
                            .symbolRenderingMode(.hierarchical)
                            .foregroundStyle(isDeleteHovered ? Color.proatError : Color.proatText3)
                            .contentTransition(.symbolEffect(.replace))
                    }
                    .buttonStyle(.borderless)
                    .help("Vervanging verwijderen")
                    .onHover { hover in
                        withAnimation(.easeInOut(duration: 0.2)) {
                            isDeleteHovered = hover
                        }
                    }
                }
            }
            .frame(maxWidth: .infinity)
        }
        .padding(.vertical, ProatSpacing.xs)
        .padding(.horizontal, ProatSpacing.s)
    }
}