import SwiftUI
import SharedModels
import SwiftData

struct VocabFlashcardView: View {
    let cards: [VocabCard]
    let speechService: SpeechService
    let onDone: () -> Void
    /// Optional deck context — when present and the title indicates a stem-
    /// changing deck, each card gets an inline conjugation toggle.
    var deckTitle: String? = nil
    /// When set, a star button appears next to the speaker on reveal so the
    /// user can mark the card for extra study.
    var markContext: ExtraStudyMarkContext? = nil

    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @State private var currentIndex = 0
    @State private var isRevealed = false
    @State private var sessionCorrect = 0
    @State private var showConjugation = false
    @State private var markedIds: Set<String> = []

    private var isStemChangingDeck: Bool {
        (deckTitle ?? "").localizedCaseInsensitiveContains("stem changing")
    }

    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

    private var currentCard: VocabCard? {
        guard currentIndex < cards.count else { return nil }
        return cards[currentIndex]
    }

    private var progress: Double {
        guard !cards.isEmpty else { return 0 }
        return Double(currentIndex) / Double(cards.count)
    }

    var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                // Progress
                VStack(spacing: 6) {
                    ProgressView(value: progress)
                        .tint(.orange)

                    Text("\(currentIndex + 1) of \(cards.count)")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
                .padding(.horizontal)

                if let card = currentCard {
                    // Front (question)
                    Text(card.front)
                        .font(.largeTitle.weight(.bold))
                        .multilineTextAlignment(.center)
                        .padding(.top, 20)

                    // Card area
                    VStack(spacing: 16) {
                        if isRevealed {
                            VStack(spacing: 12) {
                                Text(card.back)
                                    .font(.title.weight(.medium))
                                    .multilineTextAlignment(.center)

                                HStack(spacing: 12) {
                                    Button {
                                        speechService.speak(card.front)
                                    } label: {
                                        Image(systemName: "speaker.wave.2.fill")
                                            .font(.title3)
                                            .padding(12)
                                    }
                                    .glassEffect(in: .circle)

                                    if markContext != nil {
                                        Button {
                                            toggleMark()
                                        } label: {
                                            Image(systemName: currentIsMarked ? "star.fill" : "star")
                                                .font(.title3)
                                                .padding(12)
                                                .foregroundStyle(currentIsMarked ? .yellow : .secondary)
                                        }
                                        .glassEffect(in: .circle)
                                        .accessibilityLabel(currentIsMarked ? "Unmark for extra study" : "Mark for extra study")
                                    }
                                }

                                if isStemChangingDeck {
                                    Button {
                                        withAnimation(.smooth) { showConjugation.toggle() }
                                    } label: {
                                        Label(
                                            showConjugation ? "Hide conjugation" : "Show conjugation",
                                            systemImage: showConjugation ? "chevron.up" : "chevron.down"
                                        )
                                        .font(.subheadline.weight(.medium))
                                    }
                                    .buttonStyle(.bordered)
                                    .tint(.blue)

                                    if showConjugation {
                                        StemChangeConjugationView(infinitive: stripToInfinitive(card.front))
                                            .transition(.opacity.combined(with: .move(edge: .top)))
                                    }
                                }
                            }
                            .transition(.blurReplace)
                        } else {
                            VStack(spacing: 8) {
                                Image(systemName: "hand.tap")
                                    .font(.title)
                                    .foregroundStyle(.secondary)

                                Text("Tap to reveal")
                                    .font(.headline)
                                    .foregroundStyle(.secondary)
                            }
                            .transition(.blurReplace)
                        }
                    }
                    .frame(maxWidth: .infinity)
                    .frame(minHeight: 160)
                    .glassEffect(in: RoundedRectangle(cornerRadius: 20))
                    .overlay {
                        if !isRevealed {
                            Color.clear
                                .contentShape(Rectangle())
                                .onTapGesture {
                                    withAnimation(.smooth) { isRevealed = true }
                                }
                        }
                    }
                    .padding(.horizontal)

                    // Rating + navigation
                    if isRevealed {
                        VStack(spacing: 12) {
                            Text("How well did you know it?")
                                .font(.subheadline)
                                .foregroundStyle(.secondary)

                            HStack(spacing: 12) {
                                ratingButton("Again", color: .red, quality: .again)
                                ratingButton("Hard", color: .orange, quality: .hard)
                                ratingButton("Good", color: .green, quality: .good)
                                ratingButton("Easy", color: .blue, quality: .easy)
                            }
                            .padding(.horizontal)

                            // Navigation arrows
                            HStack {
                                Button {
                                    guard currentIndex > 0 else { return }
                                    withAnimation(.smooth) {
                                        isRevealed = false
                                        showConjugation = false
                                        currentIndex -= 1
                                    }
                                } label: {
                                    Label("Previous", systemImage: "chevron.left")
                                        .font(.subheadline)
                                }
                                .tint(.secondary)
                                .disabled(currentIndex == 0)

                                Spacer()

                                Button {
                                    withAnimation(.smooth) {
                                        isRevealed = false
                                        showConjugation = false
                                        currentIndex += 1
                                    }
                                } label: {
                                    Label("Skip", systemImage: "chevron.right")
                                        .font(.subheadline)
                                        .labelStyle(.titleAndIcon)
                                }
                                .tint(.secondary)
                            }
                            .padding(.horizontal)
                        }
                        .transition(.move(edge: .bottom).combined(with: .opacity))
                    }
                } else {
                    // Done
                    VStack(spacing: 16) {
                        Image(systemName: "checkmark.circle.fill")
                            .font(.system(size: 60))
                            .foregroundStyle(.green)

                        Text("Deck Complete!")
                            .font(.title.bold())

                        Text("\(sessionCorrect) / \(cards.count) correct")
                            .font(.title3)
                            .foregroundStyle(.secondary)

                        Button("Done") { onDone() }
                            .buttonStyle(.borderedProminent)
                            .tint(.orange)
                            .padding(.top, 8)
                    }
                    .padding(.top, 60)
                }
            }
            .padding(.vertical)
            .adaptiveContainer()
        }
        .animation(.smooth, value: isRevealed)
        .animation(.smooth, value: currentIndex)
        .task { loadMarks() }
    }

    private var currentIsMarked: Bool {
        guard let card = currentCard else { return false }
        return markedIds.contains(CourseCardStore.reviewKey(for: card))
    }

    private func loadMarks() {
        guard let ctx = markContext else { return }
        markedIds = ExtraStudyStore(context: cloudModelContext)
            .fetchIds(courseName: ctx.courseName, weekNumber: ctx.weekNumber)
    }

    private func toggleMark() {
        guard let card = currentCard, let ctx = markContext else { return }
        let store = ExtraStudyStore(context: cloudModelContext)
        let isNowMarked = store.toggle(
            card: card,
            courseName: ctx.courseName,
            weekNumber: ctx.weekNumber
        )
        let key = CourseCardStore.reviewKey(for: card)
        if isNowMarked {
            markedIds.insert(key)
        } else {
            markedIds.remove(key)
        }
    }

    private func ratingButton(_ label: String, color: Color, quality: ReviewQuality) -> some View {
        Button {
            rateAndAdvance(quality: quality)
        } label: {
            Text(label)
                .font(.subheadline.weight(.semibold))
                .frame(maxWidth: .infinity)
                .padding(.vertical, 12)
        }
        .tint(color)
        .glassEffect(in: RoundedRectangle(cornerRadius: 12))
    }

    private func rateAndAdvance(quality: ReviewQuality) {
        guard let card = currentCard else { return }
        CourseReviewStore(context: cloudModelContext).rate(card: card, quality: quality)

        if quality.rawValue >= 3 { sessionCorrect += 1 }

        // Next card
        withAnimation(.smooth) {
            isRevealed = false
            showConjugation = false
            currentIndex += 1
        }
    }

    /// Card fronts may be plain infinitives ("cerrar") or, in reversed decks,
    /// stored as English. Strip any reflexive-se suffix or parenthetical notes
    /// to improve the verb lookup hit rate.
    private func stripToInfinitive(_ s: String) -> String {
        var t = s.trimmingCharacters(in: .whitespacesAndNewlines)
        if let paren = t.firstIndex(of: "(") {
            t = String(t[..<paren]).trimmingCharacters(in: .whitespacesAndNewlines)
        }
        if t.hasSuffix("se") && t.count > 4 {
            // "acostarse" → "acostar" for verb lookup
            t = String(t.dropLast(2))
        }
        return t
    }
}

#Preview {
    VocabFlashcardView(cards: [], speechService: SpeechService(), onDone: {})
        .modelContainer(for: [VocabCard.self, CourseReviewCard.self], inMemory: true)
}
