import SwiftUI
import MapKit

struct GassiTreffenList: View {
    @State private var location = OneShotLocation()
    @State private var meetings: [WalkMeeting] = []
    @State private var isLoading = false
    @State private var errorMessage: String?
    @State private var showAdd = false
    @State private var cameraPosition: MapCameraPosition = .automatic
    @State private var tappedMeeting: WalkMeeting?

    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…")
            }
        }
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                Button {
                    showAdd = true
                } label: {
                    Label("Planen", systemImage: "plus")
                }
            }
        }
        .sheet(isPresented: $showAdd) {
            AddWalkSheet(coord: location.coordinate) { await load() }
        }
        .sheet(item: $tappedMeeting) { meeting in
            NavigationStack {
                GassiTreffenDetail(meetingId: meeting.id, fallbackTitle: meeting.titel) {
                    await load()
                }
                .toolbar {
                    ToolbarItem(placement: .topBarTrailing) {
                        Button("Schließen") { tappedMeeting = nil }
                    }
                }
            }
        }
        .task {
            location.request()
            await load()
        }
        .onChange(of: location.coordinate?.latitude) { _, _ in
            if let c = location.coordinate { centerOn(c) }
            Task { await load() }
        }
        .refreshable { await load() }
    }

    private func content(at coord: CLLocationCoordinate2D) -> some View {
        VStack(spacing: 0) {
            Map(position: $cameraPosition) {
                UserAnnotation()
                ForEach(meetings) { meeting in
                    Annotation(meeting.titel,
                        coordinate: CLLocationCoordinate2D(latitude: meeting.lat, longitude: meeting.lon)
                    ) {
                        Button {
                            tappedMeeting = meeting
                        } label: {
                            Image(systemName: "pawprint.circle.fill")
                                .font(.title2)
                                .foregroundStyle(.white, Color.accentColor)
                                .background(.white, in: Circle())
                                .shadow(radius: 2)
                        }
                        .buttonStyle(.plain)
                    }
                }
            }
            .frame(height: 260)
            .ignoresSafeArea(edges: .top)
            .onAppear { centerOn(coord) }
            .overlay(alignment: .topTrailing) {
                Button {
                    centerOn(coord)
                } label: {
                    Image(systemName: "location.fill")
                        .font(.callout.bold())
                        .foregroundStyle(Color.accentColor)
                        .padding(10)
                        .background(.thinMaterial, in: Circle())
                        .shadow(radius: 2)
                }
                .padding(.top, 60)
                .padding(.trailing, 12)
            }

            if isLoading && meetings.isEmpty {
                ProgressView().padding(.top, 30)
                Spacer()
            } else if let errorMessage, meetings.isEmpty {
                ContentUnavailableView(
                    "Konnte nicht laden",
                    systemImage: "wifi.slash",
                    description: Text(errorMessage)
                )
                .padding(.top, 30)
                Spacer()
            } else if meetings.isEmpty {
                ContentUnavailableView(
                    "Noch keine Treffen",
                    systemImage: "person.2",
                    description: Text("In 20 km Umkreis sind aktuell keine Gassi-Treffen geplant. Tippe oben rechts auf +, um eins zu planen.")
                )
                .padding(.top, 30)
                Spacer()
            } else {
                List(meetings) { meeting in
                    NavigationLink {
                        GassiTreffenDetail(meetingId: meeting.id, fallbackTitle: meeting.titel) {
                            await load()
                        }
                    } label: {
                        TreffenRow(meeting: meeting)
                    }
                }
                .listStyle(.plain)
            }
        }
    }

    private func centerOn(_ coord: CLLocationCoordinate2D) {
        withAnimation(.easeInOut(duration: 0.4)) {
            cameraPosition = .region(MKCoordinateRegion(
                center: coord,
                span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
            ))
        }
    }

    private func load() async {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        do {
            var path = "/api/walks?radius=20000"
            if let coord = location.coordinate {
                path = "/api/walks?lat=\(coord.latitude)&lon=\(coord.longitude)&radius=20000"
            }
            meetings = try await APIClient.shared.get(path)
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}

private struct TreffenRow: View {
    let meeting: WalkMeeting

    var body: some View {
        HStack(spacing: 12) {
            Image(systemName: "pawprint.circle.fill")
                .font(.title)
                .foregroundStyle(.white, Color.accentColor)
                .frame(width: 40)
            VStack(alignment: .leading, spacing: 4) {
                Text(meeting.titel).font(.headline)
                HStack(spacing: 6) {
                    Image(systemName: "calendar")
                    Text(formatDate(meeting.datum))
                    Text(meeting.uhrzeit)
                }
                .font(.caption.monospacedDigit())
                .foregroundStyle(.secondary)
                if let ort = meeting.ortName, !ort.isEmpty {
                    HStack(spacing: 4) {
                        Image(systemName: "mappin.and.ellipse")
                        Text(ort)
                    }
                    .font(.caption)
                    .foregroundStyle(.secondary)
                    .lineLimit(1)
                }
            }
            Spacer()
            VStack(alignment: .trailing, spacing: 2) {
                Text("\(meeting.teilnehmerCount ?? 0)/\(meeting.maxTeilnehmer)")
                    .font(.caption.bold().monospacedDigit())
                Text("Teilnehmer").font(.caption2).foregroundStyle(.secondary)
            }
        }
        .padding(.vertical, 4)
    }

    private func formatDate(_ s: String) -> String {
        let parser = DateFormatter()
        parser.locale = Locale(identifier: "en_US_POSIX")
        parser.dateFormat = "yyyy-MM-dd"
        if let d = parser.date(from: String(s.prefix(10))) {
            let out = DateFormatter()
            out.locale = Locale(identifier: "de_DE")
            out.dateFormat = "EEE d. MMM"
            return out.string(from: d)
        }
        return s
    }
}
