import SwiftUI
import SwiftData

struct GrammarExerciseView: View {
    let noteId: String
    let noteTitle: String
    @Environment(\.dismiss) private var dismiss
    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

    @State private var exercises: [GrammarExercise] = []
    @State private var currentIndex = 0
    @State private var selectedOption: Int?
    @State private var correctCount = 0
    @State private var isFinished = false

    var body: some View {
        VStack(spacing: 20) {
            if isFinished {
                finishedView
            } else if let ex = exercises[safe: currentIndex] {
                exerciseView(ex)
            }
        }
        .padding()
        .adaptiveContainer(maxWidth: 600)
        .navigationTitle("Practice: \(noteTitle)")
        .navigationBarTitleDisplayMode(.inline)
        .onAppear { exercises = Array(GrammarExercise.exercises(for: noteId).shuffled().prefix(10)) }
    }

    @ViewBuilder
    private func exerciseView(_ ex: GrammarExercise) -> some View {
        VStack(spacing: 20) {
            Text("\(currentIndex + 1) / \(exercises.count)")
                .font(.caption.weight(.medium))
                .foregroundStyle(.secondary)

            ProgressView(value: Double(currentIndex), total: Double(exercises.count))
                .tint(.purple)

            // Prompt
            Text(ex.prompt)
                .font(.subheadline)
                .foregroundStyle(.secondary)

            // Sentence
            Text(highlightBlank(ex.sentence))
                .font(.title3)
                .multilineTextAlignment(.center)
                .padding()
                .frame(maxWidth: .infinity)
                .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))

            // Options
            VStack(spacing: 10) {
                ForEach(Array(ex.options.enumerated()), id: \.offset) { index, option in
                    Button {
                        guard selectedOption == nil else { return }
                        selectedOption = index
                        if option == ex.correctAnswer { correctCount += 1 }
                    } label: {
                        HStack {
                            Text(option)
                                .font(.body.weight(.medium))
                            Spacer()
                            if let selected = selectedOption {
                                if option == ex.correctAnswer {
                                    Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
                                } else if index == selected {
                                    Image(systemName: "xmark.circle.fill").foregroundStyle(.red)
                                }
                            }
                        }
                        .padding()
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .background(optionBG(index: index, correct: ex.correctAnswer, options: ex.options), in: RoundedRectangle(cornerRadius: 10))
                    }
                    .buttonStyle(.plain)
                }
            }

            // Explanation after answer
            if selectedOption != nil {
                Text(ex.explanation)
                    .font(.callout)
                    .foregroundStyle(.secondary)
                    .padding()
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 10))
                    .transition(.opacity)
            }

            Spacer()

            if selectedOption != nil {
                Button {
                    if currentIndex + 1 < exercises.count {
                        currentIndex += 1
                        selectedOption = nil
                    } else {
                        ReviewStore.recordActivity(context: cloudModelContext)
                        withAnimation { isFinished = true }
                    }
                } label: {
                    Text(currentIndex + 1 < exercises.count ? "Next" : "See Results")
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.borderedProminent)
                .tint(.purple)
            }
        }
    }

    private var finishedView: some View {
        VStack(spacing: 20) {
            Spacer()
            Image(systemName: correctCount == exercises.count ? "star.fill" : "checkmark.circle")
                .font(.system(size: 60))
                .foregroundStyle(correctCount == exercises.count ? .yellow : .purple)

            Text("\(correctCount) / \(exercises.count)")
                .font(.system(size: 48, weight: .bold).monospacedDigit())

            Text(correctCount == exercises.count ? "Perfect!" : "Keep reviewing this topic.")
                .font(.title3)
                .foregroundStyle(.secondary)

            Button {
                dismiss()
            } label: {
                Text("Done")
                    .font(.headline)
                    .frame(maxWidth: .infinity)
                    .padding(.vertical, 12)
            }
            .buttonStyle(.borderedProminent)
            .tint(.purple)
            .padding(.horizontal)

            Spacer()
        }
    }

    private func highlightBlank(_ text: String) -> AttributedString {
        var result = AttributedString(text)
        if let range = result.range(of: "_____") {
            result[range].foregroundColor = .purple
            result[range].font = .title3.bold()
        }
        return result
    }

    private func optionBG(index: Int, correct: String, options: [String]) -> some ShapeStyle {
        guard let selected = selectedOption else { return AnyShapeStyle(.fill.quaternary) }
        if options[index] == correct { return AnyShapeStyle(.green.opacity(0.15)) }
        if index == selected { return AnyShapeStyle(.red.opacity(0.15)) }
        return AnyShapeStyle(.fill.quaternary)
    }
}

private extension Collection {
    subscript(safe index: Index) -> Element? {
        indices.contains(index) ? self[index] : nil
    }
}
