import SwiftUI
import SwiftData
import PhotosUI

struct FinishWalkSheet: View {
    let points: [GPSPoint]
    let durationSeconds: Int
    let distanceMeters: Double
    let initialPhotos: [CapturedPhoto]
    let onDiscard: () -> Void
    let onSaved: () -> Void

    @Environment(\.dismiss) private var dismiss
    @Environment(\.modelContext) private var modelContext
    @AppStorage("healthKitSyncEnabled") private var healthKitSyncEnabled = false

    @State private var name: String
    @State private var selectedDogIds: Set<Int> = []
    @State private var dogs: [Dog] = []
    @State private var isLoadingDogs = false

    @State private var photoSelection: [PhotosPickerItem] = []
    @State private var photoData: [CapturedPhoto] = []
    @State private var loadingPhotos = false

    @State private var saveState: SaveState = .idle
    @State private var errorMessage: String?

    private enum SaveState: Equatable {
        case idle
        case savingRoute
        case uploadingPhotos(done: Int, total: Int)
    }

    private let shortDistanceThreshold: Double = 50 // meters

    init(
        points: [GPSPoint],
        durationSeconds: Int,
        distanceMeters: Double,
        initialPhotos: [CapturedPhoto] = [],
        onDiscard: @escaping () -> Void,
        onSaved: @escaping () -> Void
    ) {
        self.points = points
        self.durationSeconds = durationSeconds
        self.distanceMeters = distanceMeters
        self.initialPhotos = initialPhotos
        self.onDiscard = onDiscard
        self.onSaved = onSaved

        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "de_DE")
        formatter.dateStyle = .medium
        _name = State(initialValue: "Gassi am \(formatter.string(from: .now))")
        _photoData = State(initialValue: initialPhotos)
    }

    var body: some View {
        NavigationStack {
            Form {
                if points.count >= 2 {
                    Section {
                        MiniRouteMap(track: points, lineWidth: 4)
                            .frame(height: 220)
                            .listRowInsets(EdgeInsets())
                    }
                }

                if distanceMeters < shortDistanceThreshold {
                    shortDistanceWarning
                }

                Section("Stats") {
                    LabeledContent("Distanz", value: String(format: "%.2f km", distanceMeters / 1000))
                    LabeledContent("Dauer", value: durationLabel)
                    LabeledContent("Punkte", value: "\(points.count)")
                }

                Section("Name") {
                    TextField("Name der Tour", text: $name)
                }

                Section("Hunde") {
                    if isLoadingDogs && dogs.isEmpty {
                        HStack { ProgressView(); Text("Lade Hunde…") }
                    } else if dogs.isEmpty {
                        Text("Keine Hunde gefunden. Wird gespeichert ohne Hund-Zuordnung.")
                            .font(.footnote)
                            .foregroundStyle(.secondary)
                    } else {
                        ForEach(dogs) { dog in
                            dogRow(dog)
                        }
                    }
                }

                Section {
                    PhotosPicker(
                        selection: $photoSelection,
                        maxSelectionCount: 10,
                        matching: .images
                    ) {
                        Label(
                            photoData.isEmpty ? "Fotos hinzufügen" : "Fotos ändern",
                            systemImage: "photo.badge.plus"
                        )
                    }

                    if loadingPhotos {
                        HStack { ProgressView(); Text("Lade Fotos…").font(.caption).foregroundStyle(.secondary) }
                    }

                    if !photoData.isEmpty {
                        photoStrip
                    }
                } header: {
                    Text(photoData.isEmpty ? "Fotos" : "Fotos (\(photoData.count))")
                }

                if let errorMessage {
                    Section {
                        Text(errorMessage)
                            .font(.footnote)
                            .foregroundStyle(.red)
                    }
                }
            }
            .navigationTitle("Tour speichern")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Verwerfen", role: .destructive) {
                        onDiscard()
                        dismiss()
                    }
                    .disabled(saveState != .idle)
                }
                ToolbarItem(placement: .confirmationAction) {
                    saveToolbarItem
                }
            }
            .task { await loadDogs() }
            .onChange(of: photoSelection) { _, newItems in
                Task { await loadPhotos(from: newItems) }
            }
            .interactiveDismissDisabled(saveState != .idle)
        }
    }

    @ViewBuilder
    private var saveToolbarItem: some View {
        switch saveState {
        case .idle:
            Button("Speichern") {
                Task { await save() }
            }
            .disabled(canSave == false)
        case .savingRoute:
            ProgressView()
        case .uploadingPhotos(let done, let total):
            Text("\(done)/\(total)")
                .font(.caption.monospacedDigit())
                .foregroundStyle(.secondary)
        }
    }

    private var shortDistanceWarning: some View {
        Section {
            HStack(spacing: 10) {
                Image(systemName: "exclamationmark.triangle.fill")
                    .foregroundStyle(.orange)
                Text("Sehr kurze Tour (\(Int(distanceMeters)) m). Du kannst trotzdem speichern.")
                    .font(.footnote)
            }
        }
    }

    private var photoStrip: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 8) {
                ForEach(Array(photoData.enumerated()), id: \.offset) { _, photo in
                    if let img = UIImage(data: photo.data) {
                        Image(uiImage: img)
                            .resizable()
                            .scaledToFill()
                            .frame(width: 80, height: 80)
                            .clipShape(RoundedRectangle(cornerRadius: 8))
                            .overlay(alignment: .topTrailing) {
                                if photo.location != nil {
                                    Image(systemName: "location.fill")
                                        .font(.caption2)
                                        .foregroundStyle(.white)
                                        .padding(4)
                                        .background(Color.accentColor, in: Circle())
                                        .padding(4)
                                }
                            }
                    }
                }
            }
        }
    }

    private func dogRow(_ dog: Dog) -> some View {
        let selected = selectedDogIds.contains(dog.id)
        return HStack {
            Image(systemName: selected ? "checkmark.circle.fill" : "circle")
                .foregroundStyle(selected ? Color.accentColor : .secondary)
            VStack(alignment: .leading) {
                Text(dog.name)
                if let rasse = dog.rasse, !rasse.isEmpty {
                    Text(rasse).font(.caption).foregroundStyle(.secondary)
                }
            }
            Spacer()
        }
        .contentShape(Rectangle())
        .onTapGesture {
            if selected {
                selectedDogIds.remove(dog.id)
            } else {
                selectedDogIds.insert(dog.id)
            }
        }
    }

    private var durationLabel: String {
        let mins = durationSeconds / 60
        let secs = durationSeconds % 60
        if mins >= 60 {
            return "\(mins / 60) h \(mins % 60) min"
        }
        return "\(mins) min \(secs) s"
    }

    private var canSave: Bool {
        !name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
            && points.count >= 2
            && saveState == .idle
    }

    private func loadDogs() async {
        isLoadingDogs = true
        defer { isLoadingDogs = false }
        do {
            let fetched: [Dog] = try await APIClient.shared.get("/api/dogs")
            self.dogs = fetched
            if fetched.count == 1 {
                selectedDogIds = [fetched[0].id]
            }
        } catch {
            print("FinishWalkSheet loadDogs failed: \(error)")
        }
    }

    private func loadPhotos(from items: [PhotosPickerItem]) async {
        loadingPhotos = true
        defer { loadingPhotos = false }
        var loaded: [CapturedPhoto] = initialPhotos // keep camera-captured ones
        for item in items {
            if let data = try? await item.loadTransferable(type: Data.self) {
                loaded.append(CapturedPhoto(data: data, location: nil))
            }
        }
        photoData = loaded
    }

    private func save() async {
        errorMessage = nil
        saveState = .savingRoute

        let body = RouteCreateBody(
            name: name.trimmingCharacters(in: .whitespacesAndNewlines),
            gpsTrack: points,
            distanzKm: distanceMeters / 1000,
            dauerMin: max(1, durationSeconds / 60),
            dogIds: Array(selectedDogIds),
            isPublic: false
        )

        let route: RouteDetail
        do {
            route = try await APIClient.shared.post("/api/routes", body: body)
        } catch {
            errorMessage = error.localizedDescription
            saveState = .idle
            return
        }

        if !photoData.isEmpty {
            for (index, photo) in photoData.enumerated() {
                saveState = .uploadingPhotos(done: index, total: photoData.count)
                let resized = ImageResize.resizedJPEG(from: photo.data)
                do {
                    let responseData = try await APIClient.shared.uploadFile(
                        "/api/routes/\(route.id)/photo",
                        filename: "photo_\(index + 1).jpg",
                        data: resized
                    )
                    // Persist GPS location of this photo if we have one
                    if let coord = photo.location,
                       let obj = try? JSONSerialization.jsonObject(with: responseData) as? [String: Any],
                       let fotoUrl = obj["foto_url"] as? String {
                        let loc = PhotoLocation(
                            routeId: route.id,
                            photoUrl: fotoUrl,
                            lat: coord.lat,
                            lon: coord.lon
                        )
                        modelContext.insert(loc)
                    }
                } catch {
                    errorMessage = "Tour ist gespeichert, aber Foto \(index + 1) konnte nicht hochgeladen werden: \(error.localizedDescription)"
                    saveState = .idle
                    onSaved()
                    return
                }
            }
            try? modelContext.save()
            saveState = .uploadingPhotos(done: photoData.count, total: photoData.count)
        }

        // Apple Health sync (only if user opted in)
        if healthKitSyncEnabled, points.count >= 2 {
            let endedAt = Date.now
            let startedAt = endedAt.addingTimeInterval(-Double(durationSeconds))
            await WalkHealthSync.shared.saveWalk(
                points: points,
                startedAt: startedAt,
                endedAt: endedAt,
                distanceMeters: distanceMeters
            )
        }

        onSaved()
        dismiss()
    }
}
