import SwiftUI
import MapKit

struct GassiTreffenDetail: View {
    let meetingId: Int
    let fallbackTitle: String
    let onChange: () async -> Void

    @Environment(AuthSession.self) private var auth
    @Environment(\.dismiss) private var dismiss

    @State private var meeting: WalkMeeting?
    @State private var isLoading = false
    @State private var errorMessage: String?
    @State private var isMutating = false

    @State private var dogs: [Dog] = []
    @State private var hasJoined: Bool? = nil

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 16) {
                if let meeting {
                    detailContent(meeting)
                } else if isLoading {
                    ProgressView().padding(.top, 60)
                } else if let errorMessage {
                    ContentUnavailableView(
                        "Fehler",
                        systemImage: "exclamationmark.triangle",
                        description: Text(errorMessage)
                    )
                    .padding(.top, 60)
                }
            }
            .padding()
        }
        .navigationTitle(meeting?.titel ?? fallbackTitle)
        .navigationBarTitleDisplayMode(.inline)
        .task { await load() }
    }

    @ViewBuilder
    private func detailContent(_ m: WalkMeeting) -> some View {
        Map(initialPosition: .region(MKCoordinateRegion(
            center: CLLocationCoordinate2D(latitude: m.lat, longitude: m.lon),
            span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
        ))) {
            Annotation(m.titel, coordinate: CLLocationCoordinate2D(latitude: m.lat, longitude: m.lon)) {
                Image(systemName: "pawprint.circle.fill")
                    .font(.title)
                    .foregroundStyle(.white, Color.accentColor)
                    .background(.white, in: Circle())
            }
        }
        .frame(height: 220)
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .allowsHitTesting(false)

        VStack(alignment: .leading, spacing: 6) {
            HStack {
                Image(systemName: "calendar")
                Text(formatDate(m.datum))
                Text(m.uhrzeit).monospacedDigit()
            }
            .font(.headline)

            if let ort = m.ortName, !ort.isEmpty {
                Label(ort, systemImage: "mappin.and.ellipse")
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
            }

            HStack {
                Label("\(m.teilnehmerCount ?? 0) / \(m.maxTeilnehmer) Teilnehmer", systemImage: "person.2.fill")
                if let veranstalter = m.veranstalterName {
                    Spacer()
                    Text("von \(veranstalter)")
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            }
            .font(.subheadline)
            .padding(.top, 4)
        }

        if let beschreibung = m.beschreibung, !beschreibung.isEmpty {
            Text(beschreibung)
                .font(.body)
                .padding(.top, 4)
        }

        if !isOwn(m) {
            joinButton(m)
        }

        if let errorMessage {
            Text(errorMessage)
                .font(.footnote)
                .foregroundStyle(.red)
        }
    }

    private func joinButton(_ m: WalkMeeting) -> some View {
        Button {
            Task { await toggleJoin() }
        } label: {
            HStack {
                Image(systemName: (hasJoined == true) ? "person.crop.circle.badge.minus" : "person.crop.circle.badge.plus")
                Text((hasJoined == true) ? "Verlassen" : "Beitreten").bold()
            }
            .frame(maxWidth: .infinity, minHeight: 50)
        }
        .background((hasJoined == true) ? Color.red : Color.accentColor, in: Capsule())
        .foregroundStyle(.white)
        .disabled(isMutating)
    }

    private func isOwn(_ m: WalkMeeting) -> Bool {
        m.userId == auth.profile?.id
    }

    private func load() async {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        do {
            meeting = try await APIClient.shared.get("/api/walks/\(meetingId)")
            if dogs.isEmpty {
                dogs = (try? await APIClient.shared.get("/api/dogs")) ?? []
            }
            // We don't have a clean "have I joined" endpoint, so we treat hasJoined
            // as nil → button shows "Beitreten". After successful join we set true,
            // after successful leave we set false.
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    private func toggleJoin() async {
        isMutating = true
        errorMessage = nil
        defer { isMutating = false }
        do {
            if hasJoined == true {
                try await APIClient.shared.delete("/api/walks/\(meetingId)/join")
                hasJoined = false
            } else {
                let body = WalkJoinBody(dogIds: dogs.map { $0.id })
                let _: WalkMeeting = try await APIClient.shared.post("/api/walks/\(meetingId)/join", body: body)
                hasJoined = true
            }
            await onChange()
            await load()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    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.dateStyle = .full
            return out.string(from: d)
        }
        return s
    }
}
