import SwiftUI
import SharedModels
import SwiftData

struct DeckStudyView: View {
    let deck: CourseDeck
    @Environment(\.modelContext) private var modelContext
    @Environment(\.cloudModelContextProvider) private var cloudModelContextProvider
    @Query private var textbookChapters: [TextbookChapter]
    private var cloudModelContext: ModelContext { cloudModelContextProvider() }
    @State private var isStudying = false
    @State private var speechService = SpeechService()
    @State private var deckCards: [VocabCard] = []
    @State private var expandedConjugations: Set<String> = []

    private var isStemChangingDeck: Bool {
        deck.title.localizedCaseInsensitiveContains("stem changing")
    }

    private var isTextbookDeck: Bool {
        textbookChapters.contains { $0.courseName == deck.courseName }
    }

    private var markContext: ExtraStudyMarkContext? {
        guard !isTextbookDeck else { return nil }
        return ExtraStudyMarkContext(
            courseName: deck.courseName,
            weekNumber: deck.weekNumber
        )
    }

    var body: some View {
        cardListView
            .navigationTitle(deck.title)
            .navigationBarTitleDisplayMode(.inline)
            .onAppear { loadCards() }
            .fullScreenCover(isPresented: $isStudying) {
                NavigationStack {
                    VocabFlashcardView(
                        cards: deckCards.shuffled(),
                        speechService: speechService,
                        onDone: {
                            ReviewStore.recordActivity(context: cloudModelContext)
                            isStudying = false
                        },
                        deckTitle: deck.title,
                        markContext: markContext
                    )
                    .toolbar {
                        ToolbarItem(placement: .cancellationAction) {
                            Button("Close") { isStudying = false }
                        }
                    }
                }
            }
    }

    /// Reversed stem-change decks have `front` as English, so prefer the
    /// Spanish side when the card is stored that way. Strip parenthetical
    /// notes and the reflexive `-se` ending for verb-table lookup.
    private func inferInfinitive(card: VocabCard) -> String {
        let raw: String
        if deck.isReversed {
            raw = card.back
        } else {
            raw = card.front
        }
        var t = raw.trimmingCharacters(in: .whitespacesAndNewlines)
        if let paren = t.firstIndex(of: "(") {
            t = String(t[..<paren]).trimmingCharacters(in: .whitespacesAndNewlines)
        }
        if t.hasSuffix("se") && t.count > 4 { t = String(t.dropLast(2)) }
        return t
    }

    private func loadCards() {
        let deckId = deck.id
        let descriptor = FetchDescriptor<VocabCard>(
            predicate: #Predicate<VocabCard> { $0.deckId == deckId },
            sortBy: [SortDescriptor(\VocabCard.front)]
        )
        deckCards = (try? modelContext.fetch(descriptor)) ?? []
    }

    // MARK: - Card List

    private var cardListView: some View {
        ScrollView {
            VStack(spacing: 16) {
                // Header
                VStack(spacing: 8) {
                    Text("Week \(deck.weekNumber)")
                        .font(.subheadline)
                        .foregroundStyle(.secondary)

                    Text(deck.title)
                        .font(.title2.weight(.bold))

                    HStack(spacing: 12) {
                        Label("\(deckCards.count) cards", systemImage: "rectangle.on.rectangle")

                        if deck.isReversed {
                            Label("EN → ES", systemImage: "arrow.right")
                        } else {
                            Label("ES → EN", systemImage: "arrow.right")
                        }
                    }
                    .font(.caption)
                    .foregroundStyle(.secondary)
                }
                .padding(.vertical, 8)

                // Study button
                Button {
                    withAnimation { isStudying = true }
                } label: {
                    Label("Study Flashcards", systemImage: "brain.head.profile")
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 14)
                }
                .buttonStyle(.borderedProminent)
                .tint(.orange)
                .padding(.horizontal)

                // Card list
                LazyVStack(spacing: 0) {
                    ForEach(Array(deckCards.enumerated()), id: \.offset) { _, card in
                        VStack(alignment: .leading, spacing: 8) {
                            HStack(spacing: 10) {
                                Button {
                                    speechService.speak(card.front)
                                } label: {
                                    Image(systemName: "speaker.wave.2")
                                        .font(.body)
                                        .foregroundStyle(.blue)
                                        .frame(width: 32, height: 32)
                                        .contentShape(Rectangle())
                                }
                                .buttonStyle(.borderless)

                                Text(card.front)
                                    .font(.body.weight(.medium))

                                Spacer()

                                Text(card.back)
                                    .font(.body)
                                    .foregroundStyle(.secondary)
                                    .multilineTextAlignment(.trailing)
                            }

                            // Stem-change conjugation toggle
                            if isStemChangingDeck {
                                let verb = inferInfinitive(card: card)
                                let isOpen = expandedConjugations.contains(verb)
                                Button {
                                    withAnimation(.smooth) {
                                        if isOpen {
                                            expandedConjugations.remove(verb)
                                        } else {
                                            expandedConjugations.insert(verb)
                                        }
                                    }
                                } label: {
                                    Label(
                                        isOpen ? "Hide conjugation" : "Show conjugation",
                                        systemImage: isOpen ? "chevron.up" : "chevron.down"
                                    )
                                    .font(.caption.weight(.medium))
                                }
                                .buttonStyle(.borderless)
                                .tint(.blue)
                                .padding(.leading, 42)

                                if isOpen {
                                    StemChangeConjugationView(infinitive: verb)
                                        .padding(.leading, 42)
                                        .transition(.opacity.combined(with: .move(edge: .top)))
                                }
                            }

                            // Example sentences
                            if !card.examplesES.isEmpty {
                                VStack(alignment: .leading, spacing: 6) {
                                    ForEach(Array(zip(card.examplesES, card.examplesEN).enumerated()), id: \.offset) { _, pair in
                                        VStack(alignment: .leading, spacing: 2) {
                                            Text(pair.0)
                                                .font(.caption)
                                                .italic()
                                            Text(pair.1)
                                                .font(.caption)
                                                .foregroundStyle(.secondary)
                                        }
                                    }
                                }
                                .padding(.leading, 42)
                            }
                        }
                        .padding(.horizontal, 16)
                        .padding(.vertical, 12)

                        Divider()
                            .padding(.leading, 16)
                    }
                }
                .background(.fill.quinary, in: RoundedRectangle(cornerRadius: 12))
                .padding(.horizontal)
            }
            .padding(.vertical)
            .adaptiveContainer()
        }
    }
}

#Preview {
    NavigationStack {
        DeckStudyView(deck: CourseDeck(
            id: "test", weekNumber: 1, title: "Greetings", cardCount: 5,
            courseName: "Test", isReversed: false
        ))
    }
    .modelContainer(for: [CourseDeck.self, VocabCard.self], inMemory: true)
}
