//
//  ProgressMapView.swift
//  SportsTime
//
//  Interactive map showing stadium visit progress with custom annotations.
//

import SwiftUI
import MapKit

// MARK: - Progress Map View

struct ProgressMapView: View {
    let stadiums: [Stadium]
    let visitStatus: [String: StadiumVisitStatus]
    @Binding var selectedStadium: Stadium?

    @State private var mapViewModel = MapInteractionViewModel()
    @State private var cameraPosition: MapCameraPosition = .region(MapInteractionViewModel.defaultRegion)

    var body: some View {
        Map(position: $cameraPosition, interactionModes: [.zoom, .pan]) {
            ForEach(stadiums) { stadium in
                Annotation(
                    stadium.name,
                    coordinate: CLLocationCoordinate2D(
                        latitude: stadium.latitude,
                        longitude: stadium.longitude
                    )
                ) {
                    StadiumMapPin(
                        stadium: stadium,
                        isVisited: isVisited(stadium),
                        isSelected: selectedStadium?.id == stadium.id,
                        onTap: {
                            withAnimation(.spring(response: 0.3)) {
                                if selectedStadium?.id == stadium.id {
                                    selectedStadium = nil
                                } else {
                                    selectedStadium = stadium
                                }
                            }
                        }
                    )
                }
            }
        }
        .onMapCameraChange { _ in
            mapViewModel.userDidInteract()
        }
        .overlay(alignment: .bottomTrailing) {
            if mapViewModel.shouldShowResetButton {
                Button {
                    withAnimation(.easeInOut(duration: 0.5)) {
                        cameraPosition = .region(MapInteractionViewModel.defaultRegion)
                        mapViewModel.resetToDefault()
                        selectedStadium = nil
                    }
                } label: {
                    Image(systemName: "arrow.counterclockwise")
                        .font(.title3)
                        .padding(12)
                        .background(.regularMaterial, in: Circle())
                }
                .padding()
            }
        }
        .mapStyle(.standard(elevation: .realistic))
        .clipShape(RoundedRectangle(cornerRadius: 16))
    }

    private func isVisited(_ stadium: Stadium) -> Bool {
        if case .visited = visitStatus[stadium.id] {
            return true
        }
        return false
    }
}

// MARK: - Stadium Map Pin

struct StadiumMapPin: View {
    let stadium: Stadium
    let isVisited: Bool
    let isSelected: Bool
    let onTap: () -> Void

    @Environment(\.colorScheme) private var colorScheme

    var body: some View {
        Button(action: onTap) {
            VStack(spacing: 2) {
                ZStack {
                    // Pin background
                    Circle()
                        .fill(pinColor)
                        .frame(width: pinSize, height: pinSize)
                        .shadow(color: .black.opacity(0.2), radius: 2, y: 1)

                    // Icon
                    Image(systemName: isVisited ? "checkmark" : "sportscourt")
                        .font(.system(size: iconSize, weight: .bold))
                        .foregroundStyle(.white)
                }

                // Pin pointer
                Triangle()
                    .fill(pinColor)
                    .frame(width: 10, height: 6)
                    .offset(y: -2)

                // Stadium name (when selected)
                if isSelected {
                    Text(stadium.name)
                        .font(.caption2)
                        .fontWeight(.semibold)
                        .foregroundStyle(colorScheme == .dark ? .white : .primary)
                        .padding(.horizontal, 8)
                        .padding(.vertical, 4)
                        .background {
                            Capsule()
                                .fill(colorScheme == .dark ? Color(.systemGray5) : .white)
                                .shadow(color: .black.opacity(0.15), radius: 4, y: 2)
                        }
                        .fixedSize()
                        .transition(.scale.combined(with: .opacity))
                }
            }
        }
        .buttonStyle(.plain)
        .animation(.spring(response: 0.3), value: isSelected)
    }

    private var pinColor: Color {
        if isVisited {
            return .green
        } else {
            return .orange
        }
    }

    private var pinSize: CGFloat {
        isSelected ? 36 : 28
    }

    private var iconSize: CGFloat {
        isSelected ? 16 : 12
    }
}

// MARK: - Triangle Shape

struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: rect.midX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
        path.closeSubpath()
        return path
    }
}

// MARK: - Map Region Extension

extension ProgressMapView {
    /// Calculate region to fit all stadiums
    static func region(for stadiums: [Stadium]) -> MKCoordinateRegion {
        guard !stadiums.isEmpty else {
            // Default to US center
            return MKCoordinateRegion(
                center: CLLocationCoordinate2D(latitude: 39.8283, longitude: -98.5795),
                span: MKCoordinateSpan(latitudeDelta: 50, longitudeDelta: 50)
            )
        }

        let latitudes = stadiums.map { $0.latitude }
        let longitudes = stadiums.map { $0.longitude }

        let minLat = latitudes.min()!
        let maxLat = latitudes.max()!
        let minLon = longitudes.min()!
        let maxLon = longitudes.max()!

        let center = CLLocationCoordinate2D(
            latitude: (minLat + maxLat) / 2,
            longitude: (minLon + maxLon) / 2
        )

        let span = MKCoordinateSpan(
            latitudeDelta: (maxLat - minLat) * 1.3 + 2, // Add padding
            longitudeDelta: (maxLon - minLon) * 1.3 + 2
        )

        return MKCoordinateRegion(center: center, span: span)
    }
}

// MARK: - Preview

#Preview {
    ProgressMapView(
        stadiums: [],
        visitStatus: [:],
        selectedStadium: .constant(nil)
    )
    .frame(height: 300)
    .padding()
}
