import SwiftUI
import SharedModels
import SwiftData

/// English-first verb multiple choice, driven by `VocabSessionQueue`. 4 options
/// (1 correct + 3 random distractors from the session pool). After answering:
/// reveal correct/incorrect, the verb infinitive, an example sentence, and SRS
/// rating buttons. Again/Hard requeue; a second Good or an Easy graduates.
struct VocabMultipleChoicePracticeView: View {
    var kind: VocabSessionKind = .standard

    @Environment(\.modelContext) private var localContext
    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @Environment(VerbExampleCache.self) private var exampleCache
    @Environment(\.dismiss) private var dismiss

    @State private var session: VocabSessionQueue?
    @State private var distractorPool: [Verb] = []
    @State private var options: [Verb] = []
    @State private var selectedOption: Verb? = nil
    @State private var exampleByVerbId: [Int: VerbExample] = [:]
    @State private var generatingVerbIds: Set<Int> = []
    @State private var speech = SpeechService()

    private var cloudContext: ModelContext { cloudModelContextProvider() }

    private var currentVerb: Verb? { session?.current?.verb }

    var body: some View {
        ScrollView {
            VStack(spacing: 22) {
                progressBar
                if let verb = currentVerb {
                    questionBody(verb)
                } else {
                    completionView
                }
            }
            .padding()
            .adaptiveContainer(maxWidth: 720)
        }
        .navigationTitle(kind == .reviewLearned ? "Review Learned" : "Vocab Multiple Choice")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear(perform: loadIfNeeded)
        .animation(.smooth, value: selectedOption?.id)
        .animation(.smooth, value: currentVerb?.id)
    }

    // MARK: - Progress

    private var progressBar: some View {
        VStack(spacing: 6) {
            ProgressView(value: session?.progress ?? 0)
                .tint(.purple)
            Text(progressLabel)
                .font(.caption)
                .foregroundStyle(.secondary)
        }
    }

    private var progressLabel: String {
        guard let session else { return "Loading…" }
        if session.isComplete { return "Done" }
        return "\(session.learnedCount) learned · \(session.remainingCount) to go"
    }

    // MARK: - Question

    @ViewBuilder
    private func questionBody(_ verb: Verb) -> some View {
        Text(verb.english)
            .font(.largeTitle.weight(.bold))
            .multilineTextAlignment(.center)
            .padding(.top, 12)

        if selectedOption == nil {
            optionGrid
        } else {
            revealedContent(verb)
        }
    }

    private var optionGrid: some View {
        VStack(spacing: 10) {
            ForEach(options, id: \.id) { option in
                Button {
                    selectedOption = option
                } label: {
                    Text(option.infinitive)
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 16)
                }
                .glassEffect(in: RoundedRectangle(cornerRadius: 14))
                .tint(.primary)
            }
        }
    }

    private func revealedContent(_ verb: Verb) -> some View {
        VStack(spacing: 16) {
            answerFeedback(verb)
            exampleBlock(for: verb)
            ratingButtons
        }
    }

    private func answerFeedback(_ verb: Verb) -> some View {
        let correct = (selectedOption?.id == verb.id)
        return VStack(spacing: 6) {
            Image(systemName: correct ? "checkmark.circle.fill" : "xmark.circle.fill")
                .font(.system(size: 36))
                .foregroundStyle(correct ? .green : .red)
            Text(correct ? "Correct!" : "Not quite")
                .font(.headline)
                .foregroundStyle(correct ? .green : .red)
            HStack(spacing: 10) {
                Text(verb.infinitive)
                    .font(.title2.weight(.semibold))

                Button {
                    speech.speak(verb.infinitive)
                } label: {
                    Image(systemName: "speaker.wave.2.fill")
                        .font(.body)
                        .padding(8)
                }
                .glassEffect(in: .circle)
                .accessibilityLabel("Say it out loud")
            }
            .padding(.top, 4)
        }
    }

    @ViewBuilder
    private func exampleBlock(for verb: Verb) -> some View {
        if let example = exampleByVerbId[verb.id] {
            VStack(alignment: .leading, spacing: 4) {
                Text(example.spanish).font(.subheadline).italic()
                Text(example.english).font(.caption).foregroundStyle(.secondary)
            }
            .frame(maxWidth: .infinity, alignment: .leading)
            .padding()
            .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))
        } else if generatingVerbIds.contains(verb.id) {
            HStack(spacing: 8) {
                ProgressView()
                Text("Generating example…")
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }
            .frame(maxWidth: .infinity)
            .padding()
            .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))
        }
    }

    private var ratingButtons: some View {
        VStack(spacing: 10) {
            Text("How well did you know it?")
                .font(.subheadline)
                .foregroundStyle(.secondary)
            HStack(spacing: 10) {
                ratingButton("Again", color: .red, rating: .again)
                ratingButton("Hard", color: .orange, rating: .hard)
                ratingButton("Good", color: .green, rating: .good)
                ratingButton("Easy", color: .blue, rating: .easy)
            }
        }
    }

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

    // MARK: - Completion

    private var completionView: some View {
        VStack(spacing: 16) {
            Image(systemName: "checkmark.circle.fill")
                .font(.system(size: 56))
                .foregroundStyle(.green)
            Text((session?.learnedCount ?? 0) > 0 ? "Session Complete" : "Nothing Due")
                .font(.title2.bold())
            Text(completionDetail)
                .font(.subheadline)
                .foregroundStyle(.secondary)
                .multilineTextAlignment(.center)

            HStack(spacing: 12) {
                Button {
                    studyAgain()
                } label: {
                    Label("Study Again", systemImage: "arrow.clockwise")
                        .font(.subheadline.weight(.semibold))
                        .padding(.vertical, 6)
                        .frame(maxWidth: .infinity)
                }
                .buttonStyle(.borderedProminent)
                .tint(.purple)

                Button("Done") { dismiss() }
                    .font(.subheadline.weight(.semibold))
                    .padding(.vertical, 6)
                    .frame(maxWidth: .infinity)
                    .buttonStyle(.bordered)
            }
            .padding(.top, 12)
        }
        .padding(.top, 60)
        .padding(.horizontal, 24)
    }

    private var completionDetail: String {
        let learned = session?.learnedCount ?? 0
        if learned > 0 {
            let verb = kind == .reviewLearned ? "reviewed" : "learned"
            return "\(learned) verb\(learned == 1 ? "" : "s") \(verb)"
        }
        switch kind {
        case .standard:
            return "No verbs are due right now. Study Again to review anyway."
        case .reviewLearned:
            return "Finish a Vocab session first, then come back to consolidate."
        }
    }

    // MARK: - Logic

    private func loadIfNeeded() {
        guard session == nil else { return }
        let verbs: [Verb]
        switch kind {
        case .standard:
            verbs = VocabVerbPool.sessionVerbs(localContext: localContext, cloudContext: cloudContext)
        case .reviewLearned:
            verbs = VocabVerbPool.reviewLearnedVerbs(localContext: localContext, cloudContext: cloudContext)
        }
        distractorPool = verbs
        session = VocabSessionQueue(verbs: verbs)
        prepareOptions()
        primeExampleForCurrent()
    }

    private func studyAgain() {
        session?.restart()
        selectedOption = nil
        prepareOptions()
        primeExampleForCurrent()
    }

    private func prepareOptions() {
        guard let verb = currentVerb else { options = []; return }
        let candidates = distractorPool.filter { $0.id != verb.id }
        let distractors = Array(candidates.shuffled().prefix(3))
        options = ([verb] + distractors).shuffled()
    }

    private func answer(_ rating: VocabSessionQueue.Rating) {
        guard let verbId = currentVerb?.id else { return }
        let graduation = session?.answer(rating) ?? nil
        // Review Learned is a cram pass — graduation drives the in-session
        // queue only; the long-term schedule is left untouched.
        if let graduation, kind == .standard {
            VerbReviewStore(context: cloudContext).rate(verbId: verbId, quality: graduation)
        }
        selectedOption = nil
        prepareOptions()
        primeExampleForCurrent()
    }

    private func primeExampleForCurrent() {
        guard let verb = currentVerb else { return }
        let verbId = verb.id
        if exampleByVerbId[verbId] != nil || generatingVerbIds.contains(verbId) { return }
        if let cached = exampleCache.examples(for: verbId)?.first {
            exampleByVerbId[verbId] = cached
            return
        }
        guard VerbExampleGenerator.isAvailable else { return }
        generatingVerbIds.insert(verbId)
        let infinitive = verb.infinitive
        let english = verb.english
        let formsByTense = ReferenceStore(context: localContext)
            .conjugatedForms(verbId: verbId, tenseIds: VocabExampleTenseIds.canonical)
        Task {
            do {
                let examples = try await VerbExampleGenerator.generate(
                    verbInfinitive: infinitive,
                    verbEnglish: english,
                    tenseIds: VocabExampleTenseIds.canonical,
                    formsByTense: formsByTense
                )
                exampleCache.setExamples(examples, for: verbId)
                let pick = examples.first { $0.tenseId == "ind_presente" } ?? examples.first
                if let pick, currentVerb?.id == verbId {
                    exampleByVerbId[verbId] = pick
                }
            } catch {}
            generatingVerbIds.remove(verbId)
        }
    }
}
