import SwiftUI
import SharedModels
import SwiftData

struct CourseView: View {
    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @Query(sort: \CourseDeck.weekNumber) private var decks: [CourseDeck]
    @Query(sort: \TextbookChapter.number) private var textbookChapters: [TextbookChapter]
    @AppStorage("selectedCourse") private var selectedCourse: String?
    @State private var testResults: [TestResult] = []
    @State private var extraStudyCounts: [Int: Int] = [:]

    private var textbookCourses: [String] {
        Array(Set(textbookChapters.map(\.courseName))).sorted()
    }

    private var activeCourseIsTextbook: Bool {
        textbookCourses.contains(activeCourse)
    }

    private var cloudModelContext: ModelContext { cloudModelContextProvider() }

    private var courseNames: [String] {
        let names = Set(decks.map(\.courseName))
        return names.sorted()
    }

    private var activeCourse: String {
        selectedCourse ?? courseNames.first ?? ""
    }

    private var filteredDecks: [CourseDeck] {
        decks.filter { $0.courseName == activeCourse }
    }

    private var weekGroups: [(week: Int, decks: [CourseDeck])] {
        let grouped = Dictionary(grouping: filteredDecks, by: \.weekNumber)
        return grouped.keys.sorted().map { week in
            (week, grouped[week]!.sorted { $0.title < $1.title })
        }
    }

    private func bestScore(for week: Int) -> Int? {
        let results = testResults.filter {
            $0.courseName == activeCourse && $0.weekNumber == week
            && $0.quizType != QuizType.checkpoint.rawValue
        }
        guard !results.isEmpty else { return nil }
        return results.map(\.scorePercent).max()
    }

    private func bestCheckpointScore(for week: Int) -> Int? {
        let results = testResults.filter {
            $0.courseName == activeCourse && $0.weekNumber == week
            && $0.quizType == QuizType.checkpoint.rawValue
        }
        return results.map(\.scorePercent).max()
    }

    private func hasCourseMaterial(for week: Int) -> Bool {
        guard activeCourse.contains("Beginner I") else { return false }
        return Bundle.main.url(forResource: "Beginner_I_W\(week)", withExtension: "pdf") != nil
    }

    private func shortName(_ full: String) -> String {
        full.replacingOccurrences(of: "LanGo Spanish | ", with: "")
            .replacingOccurrences(of: "LanGo Spanish ", with: "")
    }

    var body: some View {
        NavigationStack {
            List {
                if decks.isEmpty {
                    ContentUnavailableView(
                        "No Course Data",
                        systemImage: "tray",
                        description: Text("Course data is loading...")
                    )
                } else {
                    // Textbook entry (shown above course picker when available)
                    if !textbookCourses.isEmpty {
                        Section {
                            ForEach(textbookCourses, id: \.self) { name in
                                NavigationLink(value: TextbookDestination(courseName: name)) {
                                    HStack(spacing: 12) {
                                        Image(systemName: "book.fill")
                                            .font(.title3)
                                            .foregroundStyle(.indigo)
                                            .frame(width: 32)
                                        VStack(alignment: .leading, spacing: 2) {
                                            Text(name)
                                                .font(.subheadline.weight(.semibold))
                                            Text("Read chapters, do exercises")
                                                .font(.caption)
                                                .foregroundStyle(.secondary)
                                        }
                                        Spacer()
                                    }
                                }
                            }
                        } header: {
                            Text("Textbook")
                        }
                    }

                    // Course picker
                    if courseNames.count > 1 {
                        Section {
                            Picker("Course", selection: Binding(
                                get: { activeCourse },
                                set: { selectedCourse = $0 }
                            )) {
                                ForEach(courseNames, id: \.self) { name in
                                    Text(shortName(name)).tag(name)
                                }
                            }
                            .pickerStyle(.menu)
                        }
                    }

                    // Week sections
                    ForEach(weekGroups, id: \.week) { week, weekDecks in
                        Section {
                            // Course material (PDF)
                            if hasCourseMaterial(for: week) {
                                NavigationLink(value: CourseMaterialDestination(courseName: activeCourse, weekNumber: week)) {
                                    HStack(spacing: 12) {
                                        Image(systemName: "doc.richtext")
                                            .font(.title3)
                                            .foregroundStyle(.purple)
                                            .frame(width: 32)

                                        VStack(alignment: .leading, spacing: 2) {
                                            Text("Review Course Material")
                                                .font(.subheadline.weight(.semibold))
                                            Text("Week \(week) PDF")
                                                .font(.caption)
                                                .foregroundStyle(.secondary)
                                        }

                                        Spacer()
                                    }
                                }
                            }

                            // Test button
                            NavigationLink(value: WeekTestDestination(courseName: activeCourse, weekNumber: week)) {
                                HStack(spacing: 12) {
                                    Image(systemName: "pencil.and.list.clipboard")
                                        .font(.title3)
                                        .foregroundStyle(.orange)
                                        .frame(width: 32)

                                    VStack(alignment: .leading, spacing: 2) {
                                        Text("Take Test")
                                            .font(.subheadline.weight(.semibold))
                                        Text("Multiple quiz types available")
                                            .font(.caption)
                                            .foregroundStyle(.secondary)
                                    }

                                    Spacer()

                                    if let best = bestScore(for: week) {
                                        Text("\(best)%")
                                            .font(.subheadline.weight(.bold))
                                            .foregroundStyle(best >= 90 ? .green : best >= 70 ? .orange : .red)
                                    }
                                }
                            }

                            // Deck rows
                            ForEach(weekDecks) { deck in
                                NavigationLink(value: deck) {
                                    DeckRowView(deck: deck)
                                }
                            }

                            // Checkpoint exam
                            NavigationLink(value: CheckpointDestination(courseName: activeCourse, throughWeek: week)) {
                                HStack(spacing: 12) {
                                    Image(systemName: "checkmark.seal")
                                        .font(.title3)
                                        .foregroundStyle(.blue)
                                        .frame(width: 32)

                                    VStack(alignment: .leading, spacing: 2) {
                                        Text("Checkpoint Exam")
                                            .font(.subheadline.weight(.semibold))
                                        Text("Cumulative review: Weeks 1–\(week)")
                                            .font(.caption)
                                            .foregroundStyle(.secondary)
                                    }

                                    Spacer()

                                    if let best = bestCheckpointScore(for: week) {
                                        Text("\(best)%")
                                            .font(.subheadline.weight(.bold))
                                            .foregroundStyle(best >= 90 ? .green : best >= 70 ? .orange : .red)
                                    }
                                }
                            }

                            // Extra Study row — only when there are marks for this week
                            if !activeCourseIsTextbook, let markCount = extraStudyCounts[week], markCount > 0 {
                                NavigationLink(value: ExtraStudyDestination(courseName: activeCourse, weekNumber: week)) {
                                    HStack(spacing: 12) {
                                        Image(systemName: "star.fill")
                                            .font(.title3)
                                            .foregroundStyle(.yellow)
                                            .frame(width: 32)

                                        VStack(alignment: .leading, spacing: 2) {
                                            Text("Extra Study")
                                                .font(.subheadline.weight(.semibold))
                                            Text("\(markCount) marked card\(markCount == 1 ? "" : "s")")
                                                .font(.caption)
                                                .foregroundStyle(.secondary)
                                        }

                                        Spacer()
                                    }
                                }
                            }
                        } header: {
                            Text("Week \(week)")
                        }
                    }
                }
            }
            .navigationTitle(shortName(activeCourse).isEmpty ? "Course" : shortName(activeCourse))
            .onAppear {
                loadTestResults()
                loadExtraStudyCounts()
            }
            .onChange(of: activeCourse) { _, _ in
                loadExtraStudyCounts()
            }
            .navigationDestination(for: CourseDeck.self) { deck in
                DeckStudyView(deck: deck)
            }
            .navigationDestination(for: ExtraStudyDestination.self) { dest in
                ExtraStudyView(courseName: dest.courseName, weekNumber: dest.weekNumber)
            }
            .navigationDestination(for: WeekTestDestination.self) { dest in
                WeekTestView(courseName: dest.courseName, weekNumber: dest.weekNumber)
            }
            .navigationDestination(for: CheckpointDestination.self) { dest in
                CheckpointExamView(courseName: dest.courseName, throughWeek: dest.throughWeek)
            }
            .navigationDestination(for: TextbookDestination.self) { dest in
                TextbookChapterListView(courseName: dest.courseName)
            }
            .navigationDestination(for: TextbookChapter.self) { chapter in
                TextbookChapterView(chapter: chapter)
            }
            .navigationDestination(for: TextbookExerciseDestination.self) { dest in
                textbookExerciseView(for: dest)
            }
            .navigationDestination(for: CourseMaterialDestination.self) { dest in
                CourseMaterialView(weekNumber: dest.weekNumber, courseName: dest.courseName)
            }
        }
    }

    @ViewBuilder
    private func textbookExerciseView(for dest: TextbookExerciseDestination) -> some View {
        if let chapter = textbookChapters.first(where: { $0.id == dest.chapterId }) {
            TextbookExerciseView(chapter: chapter, blockIndex: dest.blockIndex)
        } else {
            ContentUnavailableView("Exercise unavailable", systemImage: "questionmark.circle")
        }
    }

    private func loadTestResults() {
        testResults = (try? cloudModelContext.fetch(FetchDescriptor<TestResult>())) ?? []
    }

    private func loadExtraStudyCounts() {
        guard !activeCourse.isEmpty else { return }
        extraStudyCounts = ExtraStudyStore(context: cloudModelContext)
            .countsByWeek(courseName: activeCourse)
    }
}

// MARK: - Navigation

struct WeekTestDestination: Hashable {
    let courseName: String
    let weekNumber: Int
}

struct CheckpointDestination: Hashable {
    let courseName: String
    let throughWeek: Int
}

struct TextbookDestination: Hashable {
    let courseName: String
}

struct ExtraStudyDestination: Hashable {
    let courseName: String
    let weekNumber: Int
}

// MARK: - Deck Row

private struct DeckRowView: View {
    let deck: CourseDeck

    var body: some View {
        HStack {
            VStack(alignment: .leading, spacing: 3) {
                Text(deck.title)
                    .font(.headline)

                HStack(spacing: 8) {
                    Label("\(deck.cardCount) cards", systemImage: "rectangle.on.rectangle")
                        .font(.caption)
                        .foregroundStyle(.secondary)

                    if deck.isReversed {
                        Text("EN → ES")
                            .font(.caption2.weight(.semibold))
                            .padding(.horizontal, 6)
                            .padding(.vertical, 2)
                            .background(.blue.opacity(0.12), in: Capsule())
                            .foregroundStyle(.blue)
                    } else {
                        Text("ES → EN")
                            .font(.caption2.weight(.semibold))
                            .padding(.horizontal, 6)
                            .padding(.vertical, 2)
                            .background(.orange.opacity(0.12), in: Capsule())
                            .foregroundStyle(.orange)
                    }
                }
            }

            Spacer()
        }
    }
}

#Preview {
    CourseView()
        .modelContainer(for: [CourseDeck.self, TestResult.self], inMemory: true)
}
