import SwiftUI
import SharedModels
import SwiftData
import PencilKit

struct CourseQuizView: View {
    let cards: [VocabCard]
    let quizType: QuizType
    let courseName: String
    let weekNumber: Int
    let isFocusMode: Bool

    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @Environment(\.dismiss) private var dismiss
    @State private var speechService = SpeechService()

    @State private var shuffledCards: [VocabCard] = []
    @State private var currentIndex = 0
    @State private var correctCount = 0
    @State private var missedItems: [MissedCourseItem] = []
    @State private var isAdvancing = false
    @State private var sentenceQuestion: SentenceQuizEngine.Question?

    // Per-question state
    @State private var userAnswer = ""
    @State private var selectedOption: Int?
    @State private var isAnswered = false
    @State private var isCorrect = false
    @State private var options: [String] = []
    @State private var hwDrawing = PKDrawing()
    @State private var hwRecognizedText = ""
    @State private var isRecognizing = false
    @FocusState private var isTypingFocused: Bool

    private var isComplete: Bool { currentIndex >= shuffledCards.count }
    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

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

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

    var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                if isComplete {
                    completionView
                } else if let card = currentCard {
                    // Progress bar
                    VStack(spacing: 4) {
                        ProgressView(value: progress)
                            .tint(isFocusMode ? .red : .orange)
                        Text("\(currentIndex + 1) of \(shuffledCards.count)")
                            .font(.caption)
                            .foregroundStyle(.secondary)
                    }
                    .padding(.horizontal)

                    // Prompt
                    if quizType.isCompleteSentence, let question = sentenceQuestion {
                        sentencePrompt(question: question)
                    } else {
                        VStack(spacing: 8) {
                            Text(quizType.promptLanguage)
                                .font(.caption.weight(.medium))
                                .foregroundStyle(.secondary)
                                .textCase(.uppercase)

                            Text(quizType.prompt(for: card))
                                .font(.title.weight(.bold))
                                .multilineTextAlignment(.center)

                            if quizType.promptLanguage == "Spanish" {
                                Button { speechService.speak(card.front) } label: {
                                    Image(systemName: "speaker.wave.2")
                                        .font(.title3)
                                }
                                .tint(.secondary)
                            }
                        }
                        .padding(.top, 8)
                    }

                    // Answer area
                    if quizType.isMultipleChoice {
                        multipleChoiceArea(card: card)
                    } else if quizType.isHandwriting {
                        handwritingArea(card: card)
                    } else {
                        typingArea(card: card)
                    }

                    // Post-answer feedback + navigation
                    if isAnswered {
                        feedbackArea(card: card)
                    }
                }
            }
            .padding()
            .adaptiveContainer()
        }
        .navigationTitle(isFocusMode ? "Focus Area" : quizType == .checkpoint ? "Checkpoint" : "Week \(weekNumber) Test")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .cancellationAction) {
                Button("Exit") { dismiss() }
            }
            ToolbarItem(placement: .primaryAction) {
                Text("\(correctCount)/\(currentIndex)")
                    .font(.subheadline.weight(.medium))
                    .foregroundStyle(.secondary)
            }
        }
        .onAppear {
            let pool: [VocabCard]
            if quizType.isCompleteSentence {
                pool = cards.filter { SentenceQuizEngine.hasValidSentence(for: $0) }
            } else {
                pool = cards
            }
            shuffledCards = pool.shuffled()
            prepareQuestion()
        }
    }

    // MARK: - Complete the Sentence

    private func sentencePrompt(question: SentenceQuizEngine.Question) -> some View {
        VStack(spacing: 12) {
            Text("Complete the Sentence")
                .font(.caption.weight(.medium))
                .foregroundStyle(.secondary)
                .textCase(.uppercase)

            Text(question.displayTemplate)
                .font(.title2.weight(.semibold))
                .multilineTextAlignment(.center)
                .fixedSize(horizontal: false, vertical: true)
                .padding(.horizontal)

            if !question.sentenceEN.isEmpty {
                Text(question.sentenceEN)
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
                    .multilineTextAlignment(.center)
                    .padding(.horizontal)
            }
        }
        .padding(.top, 8)
    }

    // MARK: - Multiple Choice

    private func multipleChoiceArea(card: VocabCard) -> some View {
        let correct = correctAnswer(for: card)
        return VStack(spacing: 10) {
            ForEach(Array(options.enumerated()), id: \.offset) { index, option in
                Button {
                    guard !isAnswered else { return }
                    selectedOption = index
                    checkMCAnswer(option, card: card)
                } label: {
                    HStack {
                        Text(option)
                            .font(.body.weight(.medium))
                        Spacer()
                        if isAnswered {
                            if option.caseInsensitiveCompare(correct) == .orderedSame {
                                Image(systemName: "checkmark.circle.fill")
                                    .foregroundStyle(.green)
                            } else if index == selectedOption {
                                Image(systemName: "xmark.circle.fill")
                                    .foregroundStyle(.red)
                            }
                        }
                    }
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.horizontal, 18)
                    .padding(.vertical, 14)
                }
                .tint(mcTint(index: index, option: option, card: card))
                .glassEffect(in: RoundedRectangle(cornerRadius: 14))
                .opacity(isAnswered && option.caseInsensitiveCompare(correct) != .orderedSame && index != selectedOption ? 0.4 : 1)
                .disabled(isAnswered)
            }
        }
        .padding(.horizontal)
    }

    private func mcTint(index: Int, option: String, card: VocabCard) -> Color {
        guard isAnswered else { return .primary }
        if option.caseInsensitiveCompare(correctAnswer(for: card)) == .orderedSame { return .green }
        if index == selectedOption { return .red }
        return .secondary
    }

    private func correctAnswer(for card: VocabCard) -> String {
        if quizType.isCompleteSentence, let blank = sentenceQuestion?.blankWord {
            return blank
        }
        return quizType.answer(for: card)
    }

    // MARK: - Handwriting

    private func handwritingArea(card: VocabCard) -> some View {
        VStack(spacing: 14) {
            if isAnswered {
                if isCorrect {
                    HStack(spacing: 8) {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundStyle(.green)
                        Text("Correct!")
                            .font(.title3.weight(.bold))
                            .foregroundStyle(.green)
                    }
                } else {
                    VStack(spacing: 8) {
                        // What was recognized
                        HStack(spacing: 8) {
                            Image(systemName: "xmark.circle.fill")
                                .foregroundStyle(.red)
                            Text(hwRecognizedText.isEmpty ? "Nothing recognized" : "Recognized: \"\(hwRecognizedText)\"")
                                .font(.subheadline)
                                .foregroundStyle(.red)
                        }

                        // Correct answer
                        VStack(spacing: 2) {
                            Text("Correct answer:")
                                .font(.caption)
                                .foregroundStyle(.secondary)
                            Text(quizType.answer(for: card))
                                .font(.title3.weight(.semibold))
                                .foregroundStyle(.primary)
                        }
                    }
                }
            } else {
                HandwritingCanvas(drawing: $hwDrawing)
                    .frame(height: 180)
                    .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 16))
                    .overlay(
                        RoundedRectangle(cornerRadius: 16)
                            .stroke(.separator, lineWidth: 1)
                    )

                if !hwRecognizedText.isEmpty {
                    Text("Recognized: \"\(hwRecognizedText)\"")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }

                HStack(spacing: 16) {
                    Button {
                        hwDrawing = PKDrawing()
                        hwRecognizedText = ""
                    } label: {
                        Label("Clear", systemImage: "trash")
                            .font(.subheadline)
                    }
                    .tint(.secondary)

                    Button {
                        submitHandwriting(card: card)
                    } label: {
                        HStack {
                            if isRecognizing {
                                ProgressView()
                                    .tint(.white)
                            }
                            Text("Check")
                                .font(.headline)
                        }
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                    }
                    .buttonStyle(.borderedProminent)
                    .disabled(hwDrawing.strokes.isEmpty || isRecognizing)
                }
            }
        }
        .padding(.horizontal)
    }

    // MARK: - Typing

    private func typingArea(card: VocabCard) -> some View {
        VStack(spacing: 14) {
            if isAnswered {
                if isCorrect {
                    HStack(spacing: 8) {
                        Image(systemName: "checkmark.circle.fill")
                            .foregroundStyle(.green)
                        Text(userAnswer)
                            .font(.title3.weight(.medium))
                            .foregroundStyle(.green)
                    }
                } else {
                    VStack(spacing: 8) {
                        HStack(spacing: 8) {
                            Image(systemName: "xmark.circle.fill")
                                .foregroundStyle(.red)
                            Text(userAnswer)
                                .font(.body)
                                .foregroundStyle(.red)
                                .strikethrough()
                        }
                        VStack(spacing: 2) {
                            Text("Correct answer:")
                                .font(.caption)
                                .foregroundStyle(.secondary)
                            Text(quizType.answer(for: card))
                                .font(.title3.weight(.semibold))
                                .foregroundStyle(.primary)
                        }
                    }
                }
            } else {
                TextField("Type \(quizType.answerLanguage) translation...", text: $userAnswer)
                    .font(.title3)
                    .multilineTextAlignment(.center)
                    .textInputAutocapitalization(.never)
                    .autocorrectionDisabled()
                    .focused($isTypingFocused)
                    .submitLabel(.done)
                    .onSubmit { submitTypingAnswer(card: card) }
                    .padding()
                    .glassEffect(in: RoundedRectangle(cornerRadius: 14))

                Button {
                    submitTypingAnswer(card: card)
                } label: {
                    Text("Check")
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.borderedProminent)
                .disabled(userAnswer.trimmingCharacters(in: .whitespaces).isEmpty)
            }
        }
        .padding(.horizontal)
    }

    // MARK: - Feedback + Navigation

    private func feedbackArea(card: VocabCard) -> some View {
        VStack(spacing: 14) {
            Divider()

            // Nav arrows
            HStack {
                Button {
                    goBack()
                } label: {
                    Label("Previous", systemImage: "chevron.left")
                        .font(.subheadline)
                }
                .tint(.secondary)
                .disabled(currentIndex == 0 || isAdvancing)

                Spacer()

                Button {
                    advance()
                } label: {
                    Label("Next", systemImage: "chevron.right")
                        .font(.subheadline.weight(.semibold))
                        .labelStyle(.titleAndIcon)
                }
                .tint(.blue)
                .disabled(isAdvancing)
            }
            .padding(.horizontal)
        }
        .transition(.move(edge: .bottom).combined(with: .opacity))
    }

    // MARK: - Completion

    private var completionView: some View {
        VStack(spacing: 20) {
            let percent = shuffledCards.isEmpty ? 0 : Int(round(Double(correctCount) / Double(shuffledCards.count) * 100))

            Image(systemName: percent >= 90 ? "star.fill" : percent >= 70 ? "hand.thumbsup.fill" : "arrow.clockwise")
                .font(.system(size: 56))
                .foregroundStyle(percent >= 90 ? .yellow : percent >= 70 ? .green : .orange)

            Text("\(percent)%")
                .font(.system(size: 60, weight: .bold, design: .rounded))

            Text("\(correctCount) of \(shuffledCards.count) correct")
                .font(.title3)
                .foregroundStyle(.secondary)

            if !missedItems.isEmpty {
                VStack(alignment: .leading, spacing: 8) {
                    Text("Missed Items")
                        .font(.headline)
                        .foregroundStyle(.red)

                    VStack(spacing: 0) {
                        ForEach(Array(missedItems.enumerated()), id: \.offset) { _, item in
                            HStack {
                                Text(item.front)
                                    .font(.subheadline.weight(.medium))
                                Spacer()
                                Text(item.back)
                                    .font(.subheadline)
                                    .foregroundStyle(.secondary)
                            }
                            .padding(.horizontal, 12)
                            .padding(.vertical, 8)
                            Divider().padding(.leading, 12)
                        }
                    }
                    .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 10))
                }
                .padding(.horizontal)
            }

            HStack(spacing: 16) {
                Button {
                    // Retake
                    correctCount = 0
                    currentIndex = 0
                    missedItems = []
                    shuffledCards = cards.shuffled()
                    resetQuestion()
                    prepareQuestion()
                } label: {
                    Label("Retake", systemImage: "arrow.clockwise")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.bordered)

                Button { dismiss() } label: {
                    Text("Done")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.borderedProminent)
                .tint(.orange)
            }
            .padding(.horizontal)
        }
        .padding(.top, 40)
    }

    // MARK: - Logic

    private func prepareQuestion() {
        guard let card = currentCard else { return }
        isAnswered = false
        isCorrect = false
        selectedOption = nil
        userAnswer = ""

        if quizType.isCompleteSentence {
            sentenceQuestion = SentenceQuizEngine.buildQuestion(for: card)
        } else {
            sentenceQuestion = nil
        }

        if quizType.isMultipleChoice {
            options = generateOptions(for: card)
        } else {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                isTypingFocused = true
            }
        }
    }

    private func resetQuestion() {
        isAnswered = false
        isCorrect = false
        selectedOption = nil
        userAnswer = ""
        options = []
        hwDrawing = PKDrawing()
        hwRecognizedText = ""
        isRecognizing = false
        sentenceQuestion = nil
    }

    private func submitHandwriting(card: VocabCard) {
        isRecognizing = true
        Task {
            let result = await HandwritingRecognizer.recognize(drawing: hwDrawing)
            await MainActor.run {
                hwRecognizedText = result.text
                isRecognizing = false
                let correct = quizType.answer(for: card)
                isCorrect = HandwritingRecognizer.checkAnswer(result: result, expected: correct)
                recordAnswer(card: card)
            }
        }
    }

    private func generateOptions(for card: VocabCard) -> [String] {
        let correct = correctAnswer(for: card)
        var distractors: [String] = []
        var seen: Set<String> = [correct.lowercased()]

        // Pull distractors from all cards in the set using each card's own front
        for other in shuffledCards.shuffled() {
            let ans = quizType.answer(for: other)
            let lower = ans.lowercased()
            if !seen.contains(lower) {
                seen.insert(lower)
                distractors.append(ans)
            }
            if distractors.count >= 3 { break }
        }

        var all = distractors + [correct]
        all.shuffle()
        return all
    }

    private func checkMCAnswer(_ selected: String, card: VocabCard) {
        let correct = correctAnswer(for: card)
        isCorrect = selected.compare(correct, options: .caseInsensitive, locale: Locale(identifier: "es")) == .orderedSame
        recordAnswer(card: card)
    }

    private func submitTypingAnswer(card: VocabCard) {
        let trimmed = userAnswer.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return }
        let correct = quizType.answer(for: card)
        isCorrect = trimmed.compare(correct, options: .caseInsensitive, locale: Locale(identifier: "es")) == .orderedSame
        recordAnswer(card: card)
    }

    private func recordAnswer(card: VocabCard) {
        isAnswered = true
        if isCorrect {
            correctCount += 1
        } else {
            missedItems.append(MissedCourseItem(front: card.front, back: card.back))
        }
    }

    private func advance() {
        guard !isAdvancing else { return }
        isAdvancing = true
        currentIndex += 1
        if isComplete {
            saveResult()
        } else {
            resetQuestion()
            prepareQuestion()
        }
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
            isAdvancing = false
        }
    }

    private func goBack() {
        guard !isAdvancing, currentIndex > 0 else { return }
        isAdvancing = true
        currentIndex -= 1
        resetQuestion()
        prepareQuestion()
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
            isAdvancing = false
        }
    }

    private func saveResult() {
        let result = TestResult(
            courseName: courseName,
            weekNumber: weekNumber,
            quizType: quizType.rawValue,
            totalQuestions: shuffledCards.count,
            correctCount: correctCount,
            missedItems: missedItems
        )
        cloudModelContext.insert(result)
        try? cloudModelContext.save()
        ReviewStore.recordActivity(context: cloudModelContext)
    }
}

#Preview {
    NavigationStack {
        CourseQuizView(
            cards: [],
            quizType: .mcEsToEn,
            courseName: "LanGo Spanish | Beginner I",
            weekNumber: 1,
            isFocusMode: false
        )
    }
    .modelContainer(for: [TestResult.self, VocabCard.self], inMemory: true)
}
