import SwiftUI
import SwiftData

struct TodayView: View {
    @Environment(\.nahbarTheme) var theme
    @Query private var people: [Person]
    @AppStorage("upcomingDaysAhead") private var daysAhead: Int = 7

    private var needsAttention: [Person] {
        people
            .filter { $0.needsAttention }
            .sorted { ($0.lastMomentDate ?? $0.createdAt) < ($1.lastMomentDate ?? $1.createdAt) }
    }

    private var birthdayPeople: [Person] {
        people.filter { $0.hasBirthdayWithin(days: daysAhead) }
    }

    // People with a scheduled reminder within the look-ahead window
    private var upcomingReminders: [Person] {
        let horizon = Calendar.current.date(byAdding: .day, value: daysAhead, to: Date()) ?? Date()
        return people
            .filter { p in
                guard let reminder = p.nextStepReminderDate, !p.nextStepCompleted else { return false }
                return reminder >= Date() && reminder <= horizon
            }
            .sorted { ($0.nextStepReminderDate ?? Date()) < ($1.nextStepReminderDate ?? Date()) }
    }

    // Open next steps NOT already shown under upcoming reminders
    private var openNextSteps: [Person] {
        let scheduledIDs = Set(upcomingReminders.map { $0.id })
        return people.filter { p in
            p.nextStep != nil && !p.nextStepCompleted && !scheduledIDs.contains(p.id)
        }
    }

    private var isEmpty: Bool {
        needsAttention.isEmpty && birthdayPeople.isEmpty && openNextSteps.isEmpty && upcomingReminders.isEmpty
    }

    private var birthdaySectionTitle: String {
        switch daysAhead {
        case 3:  return "In 3 Tagen"
        case 7:  return "Diese Woche"
        case 14: return "Nächste 2 Wochen"
        case 30: return "Nächster Monat"
        default: return "Nächste \(daysAhead) Tage"
        }
    }

    private var greeting: String {
        let hour = Calendar.current.component(.hour, from: Date())
        if hour < 12 { return "Guten Morgen." }
        if hour < 18 { return "Guten Tag." }
        return "Guten Abend."
    }

    private var formattedToday: String {
        let fmt = DateFormatter()
        fmt.locale = Locale(identifier: "de_DE")
        fmt.dateFormat = "EEEE, d. MMMM"
        return fmt.string(from: Date())
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(alignment: .leading, spacing: 32) {
                    // Header
                    VStack(alignment: .leading, spacing: 4) {
                        Text(greeting)
                            .font(.system(size: 34, weight: .light, design: theme.displayDesign))
                            .foregroundStyle(theme.contentPrimary)
                        Text(formattedToday)
                            .font(.system(size: 15, design: theme.displayDesign))
                            .foregroundStyle(theme.contentTertiary)
                    }
                    .padding(.horizontal, 20)
                    .padding(.top, 12)

                    if isEmpty {
                        emptyState
                    } else {
                        VStack(spacing: 24) {
                            if !birthdayPeople.isEmpty {
                                TodaySection(title: birthdaySectionTitle, icon: "gift") {
                                    ForEach(birthdayPeople) { person in
                                        VStack(spacing: 0) {
                                            NavigationLink(destination: PersonDetailView(person: person)) {
                                                TodayRow(person: person, hint: birthdayHint(for: person))
                                            }
                                            .buttonStyle(.plain)
                                            GiftSuggestionRow(person: person)
                                        }
                                        if person.id != birthdayPeople.last?.id {
                                            RowDivider()
                                        }
                                    }
                                }
                            }

                            if !upcomingReminders.isEmpty {
                                TodaySection(title: "Anstehende Termine", icon: "calendar") {
                                    ForEach(upcomingReminders) { person in
                                        NavigationLink(destination: PersonDetailView(person: person)) {
                                            TodayRow(person: person, hint: reminderHint(for: person))
                                        }
                                        .buttonStyle(.plain)
                                        if person.id != upcomingReminders.last?.id {
                                            RowDivider()
                                        }
                                    }
                                }
                            }

                            if !openNextSteps.isEmpty {
                                TodaySection(title: "Offene Schritte", icon: "arrow.right.circle") {
                                    ForEach(openNextSteps) { person in
                                        NavigationLink(destination: PersonDetailView(person: person)) {
                                            TodayRow(person: person, hint: person.nextStep ?? "")
                                        }
                                        .buttonStyle(.plain)
                                        if person.id != openNextSteps.last?.id {
                                            RowDivider()
                                        }
                                    }
                                }
                            }

                            if !needsAttention.isEmpty {
                                TodaySection(title: "Schon eine Weile her", icon: "clock") {
                                    ForEach(needsAttention.prefix(5)) { person in
                                        NavigationLink(destination: PersonDetailView(person: person)) {
                                            TodayRow(person: person, hint: lastSeenHint(for: person))
                                        }
                                        .buttonStyle(.plain)
                                        if person.id != Array(needsAttention.prefix(5)).last?.id {
                                            RowDivider()
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                .padding(.bottom, 40)
            }
            .background(theme.backgroundPrimary.ignoresSafeArea())
            .navigationBarHidden(true)
        }
    }

    // MARK: - Empty State

    private var emptyState: some View {
        VStack(spacing: 10) {
            Spacer().frame(height: 48)
            Text("Ein ruhiger Tag.")
                .font(.system(size: 20, weight: .light, design: theme.displayDesign))
                .foregroundStyle(theme.contentPrimary)
            Text("Oder einer, der es noch wird.")
                .font(.system(size: 15))
                .foregroundStyle(theme.contentTertiary)
        }
        .frame(maxWidth: .infinity)
    }

    // MARK: - Hints

    private func birthdayHint(for person: Person) -> String {
        guard let birthday = person.birthday else { return "" }
        let cal = Calendar.current
        let bdc = cal.dateComponents([.month, .day], from: birthday)
        for offset in 0..<7 {
            if let date = cal.date(byAdding: .day, value: offset, to: Date()) {
                let dc = cal.dateComponents([.month, .day], from: date)
                if dc.month == bdc.month && dc.day == bdc.day {
                    if offset == 0 { return "Heute Geburtstag 🎂" }
                    if offset == 1 { return "Morgen Geburtstag" }
                    return "In \(offset) Tagen Geburtstag"
                }
            }
        }
        return ""
    }

    private func reminderHint(for person: Person) -> String {
        guard let reminder = person.nextStepReminderDate else { return person.nextStep ?? "" }
        let dateStr = reminder.formatted(.dateTime.day().month(.abbreviated).hour().minute().locale(Locale(identifier: "de_DE")))
        return "\(person.nextStep ?? "") · \(dateStr)"
    }

    private func lastSeenHint(for person: Person) -> String {
        guard let last = person.lastMomentDate else { return "Noch keine Momente festgehalten" }
        let days = Int(Date().timeIntervalSince(last) / 86400)
        if days == 0 { return "Heute" }
        if days == 1 { return "Gestern" }
        if days < 7  { return "Vor \(days) Tagen" }
        if days < 30 { return "Vor \(days / 7) Woche\(days / 7 == 1 ? "" : "n")" }
        let months = days / 30
        return "Vor \(months) Monat\(months == 1 ? "" : "en")"
    }
}

// MARK: - Gift Suggestion Row

private enum GiftSuggestionState {
    case idle
    case loading
    case result(String, Date)
    case error(String)
}

struct GiftSuggestionRow: View {
    @Environment(\.nahbarTheme) var theme
    let person: Person

    @StateObject private var store = StoreManager.shared
    @State private var state: GiftSuggestionState = .idle
    @State private var isExpanded = false
    @State private var showPaywall = false

    var body: some View {
        VStack(alignment: .leading, spacing: 0) {
            Divider()
                .padding(.horizontal, 16)

            switch state {
            case .idle:
                idleButton
            case .loading:
                loadingView
            case .result(let text, let date):
                if isExpanded {
                    resultView(text: text, date: date)
                } else {
                    collapsedButton
                }
            case .error(let message):
                errorView(message: message)
            }
        }
        .onAppear {
            if let cached = AIAnalysisService.shared.loadCachedGift(for: person) {
                state = .result(cached.text, cached.generatedAt)
            }
        }
        .animation(.easeInOut(duration: 0.2), value: isExpanded)
        .sheet(isPresented: $showPaywall) { PaywallView() }
    }

    private var idleButton: some View {
        Button {
            guard store.isPro else { showPaywall = true; return }
            Task { await loadGift() }
        } label: {
            HStack(spacing: 8) {
                Image(systemName: "gift")
                    .font(.system(size: 13))
                Text("Geschenkidee vorschlagen")
                    .font(.system(size: 13))
                Spacer()
                if !store.isPro {
                    Image(systemName: "lock.fill")
                        .font(.system(size: 11))
                        .foregroundStyle(theme.contentTertiary)
                }
            }
            .foregroundStyle(store.isPro ? theme.accent : theme.contentSecondary)
            .padding(.horizontal, 16)
            .padding(.vertical, 10)
        }
        .buttonStyle(.plain)
    }

    private var collapsedButton: some View {
        Button { isExpanded = true } label: {
            HStack(spacing: 8) {
                Image(systemName: "gift")
                    .font(.system(size: 13))
                Text("Geschenkidee anzeigen")
                    .font(.system(size: 13))
                Spacer()
                Image(systemName: "chevron.down")
                    .font(.system(size: 11, weight: .medium))
            }
            .foregroundStyle(theme.accent)
            .padding(.horizontal, 16)
            .padding(.vertical, 10)
        }
        .buttonStyle(.plain)
    }

    private var loadingView: some View {
        HStack(spacing: 8) {
            ProgressView()
                .scaleEffect(0.75)
            Text("Ideen werden generiert…")
                .font(.system(size: 13))
                .foregroundStyle(theme.contentSecondary)
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
    }

    private func resultView(text: String, date: Date) -> some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Spacer()
                Button { isExpanded = false } label: {
                    Image(systemName: "chevron.up")
                        .font(.system(size: 11, weight: .medium))
                        .foregroundStyle(theme.contentTertiary)
                }
                .buttonStyle(.plain)
            }

            Text(LocalizedStringKey(text))
                .font(.system(size: 13))
                .foregroundStyle(theme.contentPrimary)
                .fixedSize(horizontal: false, vertical: true)

            HStack {
                Text(date, style: .date)
                    .font(.system(size: 11))
                    .foregroundStyle(theme.contentTertiary)
                Spacer()
                Button {
                    Task { await loadGift() }
                } label: {
                    Text("Neu laden")
                        .font(.system(size: 12))
                        .foregroundStyle(theme.accent)
                }
                .buttonStyle(.plain)
                .disabled(AIAnalysisService.shared.isRateLimited)
            }
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
    }

    private func errorView(message: String) -> some View {
        HStack {
            Text("Fehler: \(message)")
                .font(.system(size: 12))
                .foregroundStyle(theme.contentTertiary)
                .lineLimit(1)
            Spacer()
            Button {
                Task { await loadGift() }
            } label: {
                Text("Erneut versuchen")
                    .font(.system(size: 12))
                    .foregroundStyle(theme.accent)
            }
            .buttonStyle(.plain)
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 10)
    }

    @MainActor
    private func loadGift() async {
        state = .loading
        do {
            let suggestion = try await AIAnalysisService.shared.suggestGift(person: person)
            isExpanded = true
            state = .result(suggestion, Date())
        } catch {
            // Falls Cache vorhanden, zeige ihn zurück; sonst Fehler
            if let cached = AIAnalysisService.shared.loadCachedGift(for: person) {
                state = .result(cached.text, cached.generatedAt)
            } else {
                state = .error(error.localizedDescription)
            }
        }
    }
}

// MARK: - Today Section

struct TodaySection<Content: View>: View {
    @Environment(\.nahbarTheme) var theme
    let title: String
    let icon: String
    @ViewBuilder let content: Content

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            SectionHeader(title: title, icon: icon)
                .padding(.horizontal, 20)

            VStack(spacing: 0) {
                content
            }
            .background(theme.surfaceCard)
            .clipShape(RoundedRectangle(cornerRadius: theme.radiusCard))
            .padding(.horizontal, 20)
        }
    }
}

// MARK: - Today Row

struct TodayRow: View {
    @Environment(\.nahbarTheme) var theme
    let person: Person
    let hint: String

    var body: some View {
        HStack(spacing: 12) {
            PersonAvatar(person: person, size: 40)

            VStack(alignment: .leading, spacing: 2) {
                Text(person.name)
                    .font(.system(size: 15, weight: .medium, design: theme.displayDesign))
                    .foregroundStyle(theme.contentPrimary)
                if !hint.isEmpty {
                    Text(hint)
                        .font(.system(size: 13))
                        .foregroundStyle(theme.contentSecondary)
                }
            }

            Spacer()

            Image(systemName: "chevron.right")
                .font(.system(size: 11, weight: .medium))
                .foregroundStyle(theme.contentTertiary)
        }
        .padding(.horizontal, 16)
        .padding(.vertical, 12)
    }
}
