import SwiftUI
import MapKit

struct GiftkoederView: View {
    @State private var location = OneShotLocation()
    @State private var alerts: [PoisonAlert] = []
    @State private var isLoading = false
    @State private var errorMessage: String?
    @State private var showReport = false

    var body: some View {
        Group {
            if let coord = location.coordinate {
                content(at: coord)
            } else if location.error != nil {
                ContentUnavailableView(
                    "Kein Standort",
                    systemImage: "location.slash",
                    description: Text(location.error ?? "")
                )
            } else {
                ProgressView("Hole Standort…")
            }
        }
        .navigationTitle("Giftköder")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            if location.coordinate != nil {
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        showReport = true
                    } label: {
                        Label("Melden", systemImage: "exclamationmark.bubble")
                    }
                }
            }
        }
        .task { location.request() }
        .onChange(of: location.coordinate?.latitude) { _, _ in
            Task { await load() }
        }
        .sheet(isPresented: $showReport) {
            if let coord = location.coordinate {
                ReportPoisonSheet(coord: coord) { await load() }
            }
        }
    }

    private func content(at coord: CLLocationCoordinate2D) -> some View {
        VStack(spacing: 0) {
            Map(initialPosition: .region(MKCoordinateRegion(
                center: coord,
                span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
            ))) {
                UserAnnotation()
                ForEach(alerts) { alert in
                    Annotation(alert.typ ?? "Giftköder",
                        coordinate: CLLocationCoordinate2D(latitude: alert.lat, longitude: alert.lon)
                    ) {
                        Image(systemName: "exclamationmark.octagon.fill")
                            .font(.title2)
                            .foregroundStyle(.red)
                            .background(.white, in: Circle())
                            .shadow(radius: 2)
                    }
                }
            }
            .frame(height: 260)
            .ignoresSafeArea(edges: .top)

            if alerts.isEmpty && !isLoading {
                ContentUnavailableView(
                    "Keine Meldungen im Umkreis",
                    systemImage: "checkmark.shield",
                    description: Text("In 5 km Umkreis sind aktuell keine aktiven Warnungen.")
                )
                .padding(.top, 30)
                Spacer()
            } else {
                List(alerts) { alert in
                    PoisonRow(alert: alert)
                }
                .listStyle(.plain)
            }
        }
    }

    private func load() async {
        guard let coord = location.coordinate else { return }
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        do {
            alerts = try await APIClient.shared.get(
                "/api/poison?lat=\(coord.latitude)&lon=\(coord.longitude)&radius=5000"
            )
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}

private struct PoisonRow: View {
    let alert: PoisonAlert

    var body: some View {
        HStack(spacing: 12) {
            Image(systemName: "exclamationmark.octagon.fill")
                .foregroundStyle(.red)
                .frame(width: 28)
            VStack(alignment: .leading, spacing: 2) {
                HStack {
                    Text((alert.typ ?? "Unbekannt").capitalized)
                        .font(.subheadline.bold())
                    Spacer()
                    if let d = alert.distanzM {
                        Text(distLabel(d))
                            .font(.caption.monospacedDigit())
                            .foregroundStyle(.secondary)
                    }
                }
                if let b = alert.beschreibung, !b.isEmpty {
                    Text(b).font(.caption).foregroundStyle(.secondary).lineLimit(2)
                }
                if let m = alert.melderName {
                    Text("Gemeldet von \(m)").font(.caption2).foregroundStyle(.tertiary)
                }
            }
        }
        .padding(.vertical, 4)
    }

    private func distLabel(_ m: Int) -> String {
        if m >= 1000 { return String(format: "%.1f km", Double(m) / 1000) }
        return "\(m) m"
    }
}

private struct ReportPoisonSheet: View {
    @Environment(\.dismiss) private var dismiss
    let coord: CLLocationCoordinate2D
    let onSaved: () async -> Void

    @State private var typ = "unbekannt"
    @State private var beschreibung = ""
    @State private var isSaving = false
    @State private var errorMessage: String?

    private let typen = ["unbekannt", "wurst", "tabletten", "glas", "metall", "wurfdose", "rattengift"]

    var body: some View {
        NavigationStack {
            Form {
                Section("Standort") {
                    Text(String(format: "%.5f, %.5f", coord.latitude, coord.longitude))
                        .font(.caption.monospacedDigit())
                }
                Section("Art") {
                    Picker("Typ", selection: $typ) {
                        ForEach(typen, id: \.self) { Text($0.capitalized) }
                    }
                }
                Section("Beschreibung (optional)") {
                    TextField("Was gefunden? Wo genau? Hinweise für andere…", text: $beschreibung, axis: .vertical)
                        .lineLimit(3...6)
                }
                if let errorMessage {
                    Section { Text(errorMessage).font(.footnote).foregroundStyle(.red) }
                }
            }
            .navigationTitle("Giftköder melden")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Abbrechen") { dismiss() }.disabled(isSaving)
                }
                ToolbarItem(placement: .confirmationAction) {
                    if isSaving { ProgressView() }
                    else { Button("Melden") { Task { await save() } } }
                }
            }
        }
    }

    private func save() async {
        isSaving = true
        errorMessage = nil
        defer { isSaving = false }
        let body = PoisonCreateBody(
            lat: coord.latitude,
            lon: coord.longitude,
            beschreibung: beschreibung.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? nil : beschreibung,
            typ: typ
        )
        do {
            let _: PoisonAlert = try await APIClient.shared.post("/api/poison", body: body)
            await onSaved()
            dismiss()
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}
