import SwiftUI
import SharedModels
import SwiftData

struct VerbDetailView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(VerbExampleCache.self) private var exampleCache
    @Environment(ReflexiveVerbStore.self) private var reflexiveStore
    @State private var speechService = SpeechService()
    let verb: Verb
    @State private var selectedTense: TenseInfo = TenseInfo.all[0]

    @State private var examples: [VerbExample] = []
    @State private var examplesState: ExamplesState = .idle

    private enum ExamplesState: Equatable {
        case idle
        case loading
        case loaded
        case unavailable
        case failed(String)
    }

    private static let exampleTenseIds: [String] = [
        TenseID.ind_presente.rawValue,
        TenseID.ind_preterito.rawValue,
        TenseID.ind_imperfecto.rawValue,
        TenseID.ind_futuro.rawValue,
        TenseID.subj_presente.rawValue,
        TenseID.imp_afirmativo.rawValue,
    ]

    private var formsForTense: [VerbForm] {
        ReferenceStore(context: modelContext).fetchForms(verbId: verb.id, tenseId: selectedTense.id)
    }

    private var reflexiveEntries: [ReflexiveVerb] {
        reflexiveStore.entries(for: verb.infinitive)
    }

    var body: some View {
        List {
            Section {
                LabeledContent("English", value: verb.english)
                LabeledContent("Ending", value: "-\(verb.ending)")
                LabeledContent("Level", value: VerbLevel(rawValue: verb.level)?.displayName ?? verb.level.capitalized)
                if verb.reflexive > 0 {
                    LabeledContent("Reflexive", value: verb.reflexive == 2 ? "Always" : "Yes")
                }
            } header: {
                Text("Info")
            }

            if !reflexiveEntries.isEmpty {
                reflexiveSection
            }

            Section {
                Picker("Tense", selection: $selectedTense) {
                    ForEach(TenseInfo.all) { tense in
                        Text(tense.english)
                            .tag(tense)
                    }
                }
                .pickerStyle(.menu)

                if formsForTense.isEmpty {
                    ContentUnavailableView("No forms loaded", systemImage: "exclamationmark.triangle")
                } else {
                    ForEach(formsForTense, id: \.personIndex) { form in
                        VStack(alignment: .leading, spacing: 2) {
                            HStack {
                                Text(TenseInfo.persons[form.personIndex])
                                    .foregroundStyle(.secondary)
                                    .frame(minWidth: 100, alignment: .leading)
                                Text(form.form)
                                    .fontWeight(form.regularity != "ordinary" ? .semibold : .regular)
                                    .foregroundStyle(form.regularity != "ordinary" ? .red : .primary)
                            }
                            Text(EnglishConjugator.translate(
                                english: verb.english,
                                tenseId: selectedTense.id,
                                personIndex: form.personIndex
                            ))
                            .font(.caption)
                            .foregroundStyle(.secondary)
                        }
                    }

                    if formsForTense.contains(where: { $0.regularity != "ordinary" }) {
                        Label("Red indicates an irregular conjugation", systemImage: "info.circle")
                            .font(.caption)
                            .foregroundStyle(.secondary)
                    }
                }
            } header: {
                Text("Conjugation")
            }

            examplesSection
        }
        .navigationTitle(verb.infinitive)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    speechService.speak(verb.infinitive)
                } label: {
                    Image(systemName: "speaker.wave.2.fill")
                }
                .tint(.secondary)
            }
        }
        .task(id: verb.id) {
            await loadExamples()
        }
    }

    // MARK: - Reflexive

    private var reflexiveSection: some View {
        Section {
            ForEach(Array(reflexiveEntries.enumerated()), id: \.offset) { _, entry in
                VStack(alignment: .leading, spacing: 4) {
                    HStack(alignment: .firstTextBaseline, spacing: 8) {
                        Text(entry.infinitive)
                            .font(.body.weight(.semibold))
                            .italic()
                        if let hint = entry.usageHint, !hint.isEmpty {
                            Text(hint)
                                .font(.caption.weight(.medium))
                                .foregroundStyle(.tint)
                        }
                    }
                    Text(entry.english)
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
                .padding(.vertical, 2)
            }
        } header: {
            Text("Reflexive")
        } footer: {
            if reflexiveEntries.contains(where: { $0.usageHint != nil }) {
                Text("Highlighted words are prepositions or phrases this verb commonly pairs with.")
                    .font(.caption2)
            }
        }
    }

    // MARK: - Examples

    @ViewBuilder
    private var examplesSection: some View {
        Section {
            switch examplesState {
            case .idle, .loading:
                HStack(spacing: 10) {
                    ProgressView()
                    Text("Generating examples…")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            case .unavailable:
                Label("Examples require Apple Intelligence on this device.", systemImage: "sparkles")
                    .font(.caption)
                    .foregroundStyle(.secondary)
            case .failed(let message):
                Label(message, systemImage: "exclamationmark.triangle")
                    .font(.caption)
                    .foregroundStyle(.secondary)
            case .loaded:
                if examples.isEmpty {
                    Label("No examples available.", systemImage: "text.quote")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                } else {
                    ForEach(Array(examples.enumerated()), id: \.offset) { _, example in
                        VStack(alignment: .leading, spacing: 4) {
                            if let info = TenseInfo.find(example.tenseId) {
                                Text(info.english)
                                    .font(.caption2.weight(.semibold))
                                    .foregroundStyle(.tint)
                            }
                            Text(example.spanish)
                                .font(.body)
                                .italic()
                            Text(example.english)
                                .font(.caption)
                                .foregroundStyle(.secondary)
                        }
                        .padding(.vertical, 2)
                    }
                }
            }
        } header: {
            Text("Examples")
        }
    }

    private func loadExamples() async {
        // Reset state when navigating between verbs via NavigationSplitView.
        examples = []
        examplesState = .idle

        if let cached = exampleCache.examples(for: verb.id), !cached.isEmpty {
            examples = cached
            examplesState = .loaded
            return
        }

        guard VerbExampleGenerator.isAvailable else {
            examplesState = .unavailable
            return
        }

        examplesState = .loading
        do {
            let formsByTense = ReferenceStore(context: modelContext)
                .conjugatedForms(verbId: verb.id, tenseIds: Self.exampleTenseIds)
            let generated = try await VerbExampleGenerator.generate(
                verbInfinitive: verb.infinitive,
                verbEnglish: verb.english,
                tenseIds: Self.exampleTenseIds,
                formsByTense: formsByTense
            )
            guard !generated.isEmpty else {
                examplesState = .failed("Could not generate examples.")
                return
            }
            exampleCache.setExamples(generated, for: verb.id)
            examples = generated
            examplesState = .loaded
        } catch {
            examplesState = .failed("Could not generate examples.")
        }
    }
}

#Preview {
    NavigationStack {
        VerbDetailView(verb: Verb(id: 1, infinitive: "hablar", english: "to speak", rank: 1, ending: "ar", reflexive: 0, level: "basic"))
    }
    .modelContainer(for: [Verb.self, VerbForm.self], inMemory: true)
    .environment(VerbExampleCache())
    .environment(ReflexiveVerbStore())
}
