import SwiftUI

struct StatisticsView: View {
    @Environment(AuthSession.self) private var auth

    @State private var routes: [RouteListItem] = []
    @State private var isLoading = false
    @State private var errorMessage: String?

    var body: some View {
        NavigationStack {
            content
                .navigationTitle("Statistik")
                .task { await load() }
                .refreshable { await load() }
        }
    }

    @ViewBuilder
    private var content: some View {
        if isLoading && routes.isEmpty {
            ProgressView()
        } else if let errorMessage, routes.isEmpty {
            ContentUnavailableView(
                "Konnte Statistik nicht laden",
                systemImage: "exclamationmark.triangle",
                description: Text(errorMessage)
            )
        } else if myRoutes.isEmpty {
            ContentUnavailableView(
                "Noch keine Touren",
                systemImage: "chart.bar.xaxis",
                description: Text("Sobald du Gassi-Touren aufnimmst, siehst du hier deine Zahlen.")
            )
        } else {
            List {
                Section("Diese Woche") {
                    stats(in: weekRoutes)
                }
                Section("Diesen Monat") {
                    stats(in: monthRoutes)
                }
                Section("Allzeit") {
                    stats(in: myRoutes)
                    LabeledContent("Längste Tour", value: longestKm)
                    LabeledContent("Aktuelle Serie", value: streakLabel)
                }
            }
        }
    }

    private func stats(in r: [RouteListItem]) -> some View {
        Group {
            LabeledContent("Distanz", value: String(format: "%.1f km", r.compactMap(\.distanzKm).reduce(0, +)))
            LabeledContent("Dauer", value: formatTotalMinutes(r.compactMap(\.dauerMin).reduce(0, +)))
            LabeledContent("Touren", value: "\(r.count)")
        }
    }

    private func load() async {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        do {
            routes = try await APIClient.shared.get("/api/routes")
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    // MARK: - Filtering

    private var myId: Int? { auth.profile?.id }

    private var myRoutes: [RouteListItem] {
        guard let myId else { return [] }
        return routes.filter { $0.userId == myId }
    }

    private var weekRoutes: [RouteListItem] {
        let cal = Calendar.current
        let start = cal.dateInterval(of: .weekOfYear, for: .now)?.start ?? .now
        return myRoutes.filter { dateFromAPI($0.createdAt) >= start }
    }

    private var monthRoutes: [RouteListItem] {
        let cal = Calendar.current
        let start = cal.dateInterval(of: .month, for: .now)?.start ?? .now
        return myRoutes.filter { dateFromAPI($0.createdAt) >= start }
    }

    // MARK: - Derived

    private var longestKm: String {
        let max = myRoutes.compactMap(\.distanzKm).max() ?? 0
        return String(format: "%.2f km", max)
    }

    private var streakLabel: String {
        let days = currentStreakDays()
        if days == 0 { return "—" }
        return days == 1 ? "1 Tag" : "\(days) Tage"
    }

    private func currentStreakDays() -> Int {
        let cal = Calendar.current
        let doneDays = Set(myRoutes.map { cal.startOfDay(for: dateFromAPI($0.createdAt)) })
        guard !doneDays.isEmpty else { return 0 }

        var day = cal.startOfDay(for: .now)
        if !doneDays.contains(day) {
            day = cal.date(byAdding: .day, value: -1, to: day) ?? day
        }
        var streak = 0
        while doneDays.contains(day) {
            streak += 1
            day = cal.date(byAdding: .day, value: -1, to: day) ?? day
        }
        return streak
    }

    private func dateFromAPI(_ str: String?) -> Date {
        guard let str else { return .distantPast }
        let parser = DateFormatter()
        parser.locale = Locale(identifier: "en_US_POSIX")
        parser.timeZone = TimeZone(identifier: "UTC")
        for format in ["yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm:ssZ"] {
            parser.dateFormat = format
            if let d = parser.date(from: str) { return d }
        }
        return .distantPast
    }

    private func formatTotalMinutes(_ totalMin: Int) -> String {
        let h = totalMin / 60
        let m = totalMin % 60
        if h > 0 { return "\(h) h \(m) min" }
        return "\(m) min"
    }
}
