//
//  QuickAddItemSheet.swift
//  SportsTime
//
//  Polished sheet for adding/editing custom itinerary items
//

import SwiftUI
import MapKit

/// Streamlined sheet for adding custom items to a trip itinerary
struct QuickAddItemSheet: View {
    @Environment(\.dismiss) private var dismiss
    @Environment(\.colorScheme) private var colorScheme

    let tripId: UUID
    let day: Int
    let existingItem: ItineraryItem?
    var onSave: (ItineraryItem) -> Void

    // Form state
    @State private var selectedCategory: ItemCategory = .restaurant
    @State private var title: String = ""
    @State private var selectedPlace: MKMapItem?
    @State private var showLocationSearch = false
    @FocusState private var isTitleFocused: Bool

    // Derived state
    private var isEditing: Bool { existingItem != nil }

    private var canSave: Bool {
        !title.trimmingCharacters(in: .whitespaces).isEmpty
    }

    private var placeholderText: String {
        switch selectedCategory {
        case .restaurant:
            return "e.g., Lunch at the stadium"
        case .attraction:
            return "e.g., Visit the art museum"
        case .fuel:
            return "e.g., Fill up before leaving"
        case .hotel:
            return "e.g., Check in at Marriott"
        case .other:
            return "e.g., Pick up tickets"
        }
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: Theme.Spacing.lg) {
                    // Category picker card
                    categoryCard

                    // Description card
                    descriptionCard

                    // Location card
                    locationCard
                }
                .padding(.horizontal, Theme.Spacing.lg)
                .padding(.top, Theme.Spacing.md)
                .padding(.bottom, Theme.Spacing.xxl)
            }
            .scrollDismissesKeyboard(.interactively)
            .background(Theme.backgroundGradient(colorScheme))
            .navigationTitle(isEditing ? "Edit Item" : "Add to Day \(day)")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                    .foregroundStyle(Theme.textSecondary(colorScheme))
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button(isEditing ? "Save" : "Add") {
                        saveItem()
                    }
                    .fontWeight(.semibold)
                    .foregroundStyle(canSave ? Theme.warmOrange : Theme.textMuted(colorScheme))
                    .disabled(!canSave)
                    .accessibilityLabel(saveButtonAccessibilityLabel)
                }
            }
            .sheet(isPresented: $showLocationSearch) {
                PlaceSearchSheet(category: selectedCategory) { place in
                    Theme.Animation.withMotion(Theme.Animation.spring) {
                        selectedPlace = place
                    }
                    // Use place name as title if empty
                    if title.trimmingCharacters(in: .whitespaces).isEmpty,
                       let placeName = place.name {
                        title = placeName
                    }
                }
            }
            .onAppear {
                loadExistingItem()
                // Focus text field after a brief delay
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    isTitleFocused = true
                }
            }
        }
    }

    // MARK: - Category Card

    private var categoryCard: some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.md) {
            sectionHeader(title: "What type?", icon: "square.grid.2x2")

            CategoryPicker(selectedCategory: $selectedCategory)
        }
        .cardStyle()
    }

    // MARK: - Description Card

    private var descriptionCard: some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.md) {
            sectionHeader(title: "Description", icon: "text.alignleft")

            VStack(spacing: Theme.Spacing.xs) {
                TextField(placeholderText, text: $title, axis: .vertical)
                    .textFieldStyle(.plain)
                    .font(.body)
                    .lineLimit(1...3)
                    .focused($isTitleFocused)
                    .padding(Theme.Spacing.md)
                    .background(inputBackground)
                    .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
                    .overlay(
                        RoundedRectangle(cornerRadius: Theme.CornerRadius.medium)
                            .strokeBorder(
                                isTitleFocused ? Theme.warmOrange : Theme.surfaceGlow(colorScheme),
                                lineWidth: isTitleFocused ? 2 : 1
                            )
                    )
                    .accessibilityLabel("Item description")
                    .accessibilityHint(placeholderText)

                // Character hint
                if !title.isEmpty {
                    HStack {
                        Spacer()
                        Text("\(title.count) characters")
                            .font(.caption2)
                            .foregroundStyle(Theme.textMuted(colorScheme))
                    }
                }
            }
        }
        .cardStyle()
    }

    private var inputBackground: Color {
        colorScheme == .dark
            ? Color.white.opacity(0.05)
            : Color.black.opacity(0.03)
    }

    // MARK: - Location Card

    private var locationCard: some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.md) {
            sectionHeader(title: "Location", icon: "mappin.and.ellipse", optional: true)

            if let place = selectedPlace {
                selectedLocationRow(place)
            } else {
                addLocationButton
            }
        }
        .cardStyle()
    }

    private var addLocationButton: some View {
        Button {
            showLocationSearch = true
        } label: {
            HStack(spacing: Theme.Spacing.sm) {
                ZStack {
                    Circle()
                        .fill(Theme.warmOrange.opacity(0.15))
                        .frame(width: 40, height: 40)

                    Image(systemName: "plus")
                        .font(.body.weight(.semibold))
                        .foregroundStyle(Theme.warmOrange)
                }

                VStack(alignment: .leading, spacing: 2) {
                    Text("Add a location")
                        .font(.body)
                        .fontWeight(.medium)
                        .foregroundStyle(Theme.textPrimary(colorScheme))

                    Text("Search for nearby places")
                        .font(.caption)
                        .foregroundStyle(Theme.textMuted(colorScheme))
                }

                Spacer()

                Image(systemName: "chevron.right")
                    .font(.caption.weight(.semibold))
                    .foregroundStyle(Theme.textMuted(colorScheme))
                    .accessibilityHidden(true)
            }
            .padding(Theme.Spacing.md)
            .background(inputBackground)
            .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
            .overlay(
                RoundedRectangle(cornerRadius: Theme.CornerRadius.medium)
                    .strokeBorder(Theme.surfaceGlow(colorScheme), lineWidth: 1)
            )
        }
        .buttonStyle(.plain)
        .pressableStyle()
        .accessibilityLabel("Add location")
        .accessibilityHint("Search for nearby places to add to this item")
    }

    private func selectedLocationRow(_ place: MKMapItem) -> some View {
        HStack(spacing: Theme.Spacing.sm) {
            // Location icon with accent
            ZStack {
                Circle()
                    .fill(Theme.warmOrange.opacity(0.15))
                    .frame(width: 44, height: 44)

                Image(systemName: "mappin.circle.fill")
                    .font(.title2)
                    .foregroundStyle(Theme.warmOrange)
            }

            VStack(alignment: .leading, spacing: Theme.Spacing.xxs) {
                Text(place.name ?? "Selected Location")
                    .font(.body)
                    .fontWeight(.medium)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                if let address = formatAddress(for: place) {
                    Text(address)
                        .font(.caption)
                        .foregroundStyle(Theme.textSecondary(colorScheme))
                        .lineLimit(1)
                }
            }

            Spacer()

            // Remove button
            Button {
                Theme.Animation.withMotion(Theme.Animation.spring) {
                    selectedPlace = nil
                }
            } label: {
                Image(systemName: "xmark.circle.fill")
                    .font(.title3)
                    .foregroundStyle(Theme.textMuted(colorScheme))
            }
            .minimumHitTarget()
            .accessibilityLabel("Remove \(place.name ?? "location")")
            .accessibilityHint("Double-tap to remove this location from the item")
        }
        .padding(Theme.Spacing.md)
        .background(Theme.warmOrange.opacity(0.08))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
        .overlay(
            RoundedRectangle(cornerRadius: Theme.CornerRadius.medium)
                .strokeBorder(Theme.warmOrange.opacity(0.3), lineWidth: 1)
        )
    }

    // MARK: - Section Header

    private func sectionHeader(title: String, icon: String, optional: Bool = false) -> some View {
        HStack(spacing: Theme.Spacing.xs) {
            Image(systemName: icon)
                .font(.caption)
                .foregroundStyle(Theme.warmOrange)
                .accessibilityHidden(true)

            Text(title)
                .font(.subheadline)
                .fontWeight(.semibold)
                .foregroundStyle(Theme.textPrimary(colorScheme))

            if optional {
                Text("optional")
                    .font(.caption2)
                    .foregroundStyle(Theme.textMuted(colorScheme))
                    .padding(.horizontal, 6)
                    .padding(.vertical, 2)
                    .background(Theme.surfaceGlow(colorScheme))
                    .clipShape(Capsule())
            }
        }
    }

    // MARK: - Helpers

    private var saveButtonAccessibilityLabel: String {
        let trimmedTitle = title.trimmingCharacters(in: .whitespaces)
        if trimmedTitle.isEmpty {
            return isEditing ? "Save, button disabled" : "Add, button disabled"
        }
        return isEditing ? "Save \(trimmedTitle)" : "Add \(trimmedTitle) to Day \(day)"
    }

    private func loadExistingItem() {
        guard let existing = existingItem,
              case .custom(let info) = existing.kind else { return }

        title = info.title

        // Find category by icon
        if let category = ItemCategory.allCases.first(where: { $0.icon == info.icon }) {
            selectedCategory = category
        }

        // Restore location if present
        if let lat = info.latitude,
           let lon = info.longitude {
            let placemark = MKPlacemark(
                coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lon)
            )
            let mapItem = MKMapItem(placemark: placemark)
            mapItem.name = info.title
            selectedPlace = mapItem
        }
    }

    private func saveItem() {
        let trimmedTitle = title.trimmingCharacters(in: .whitespaces)
        guard !trimmedTitle.isEmpty else { return }

        let customInfo: CustomInfo
        let item: ItineraryItem

        if let place = selectedPlace {
            // Item with location
            let coordinate = place.placemark.coordinate
            customInfo = CustomInfo(
                title: trimmedTitle,
                icon: selectedCategory.icon,
                time: nil,
                latitude: coordinate.latitude,
                longitude: coordinate.longitude,
                address: formatAddress(for: place)
            )
        } else {
            // Item without location
            customInfo = CustomInfo(
                title: trimmedTitle,
                icon: selectedCategory.icon,
                time: nil
            )
        }

        if let existing = existingItem {
            // Update existing item
            item = ItineraryItem(
                id: existing.id,
                tripId: existing.tripId,
                day: existing.day,
                sortOrder: existing.sortOrder,
                kind: .custom(customInfo),
                modifiedAt: Date()
            )
        } else {
            // Create new item
            item = ItineraryItem(
                tripId: tripId,
                day: day,
                sortOrder: 0.0,
                kind: .custom(customInfo)
            )
        }

        onSave(item)
        dismiss()
    }

    private func formatAddress(for place: MKMapItem) -> String? {
        let placemark = place.placemark
        var components: [String] = []

        if let thoroughfare = placemark.thoroughfare {
            components.append(thoroughfare)
        }
        if let locality = placemark.locality {
            components.append(locality)
        }
        if let administrativeArea = placemark.administrativeArea {
            components.append(administrativeArea)
        }

        return components.isEmpty ? nil : components.joined(separator: ", ")
    }
}

// MARK: - Card Style Modifier

private extension View {
    func cardStyle() -> some View {
        modifier(AddItemCardStyle())
    }
}

private struct AddItemCardStyle: ViewModifier {
    @Environment(\.colorScheme) private var colorScheme

    func body(content: Content) -> some View {
        content
            .padding(Theme.Spacing.lg)
            .background(Theme.cardBackground(colorScheme))
            .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.large))
            .overlay {
                RoundedRectangle(cornerRadius: Theme.CornerRadius.large)
                    .strokeBorder(Theme.surfaceGlow(colorScheme), lineWidth: 1)
            }
            .shadow(color: Theme.cardShadow(colorScheme), radius: 8, y: 4)
    }
}

// MARK: - Pressable Button Style

private extension View {
    func pressableStyle() -> some View {
        buttonStyle(PressableStyle())
    }
}

private struct PressableStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .scaleEffect(configuration.isPressed ? 0.97 : 1.0)
            .animation(
                Theme.Animation.prefersReducedMotion ? nil : .spring(response: 0.3, dampingFraction: 0.7),
                value: configuration.isPressed
            )
    }
}

// MARK: - Previews

#Preview("New Item - Light") {
    QuickAddItemSheet(
        tripId: UUID(),
        day: 1,
        existingItem: nil
    ) { item in
        print("Saved: \(item)")
    }
    .preferredColorScheme(.light)
}

#Preview("New Item - Dark") {
    QuickAddItemSheet(
        tripId: UUID(),
        day: 3,
        existingItem: nil
    ) { item in
        print("Saved: \(item)")
    }
    .preferredColorScheme(.dark)
}

#Preview("Edit Item") {
    let existing = ItineraryItem(
        tripId: UUID(),
        day: 2,
        sortOrder: 1.0,
        kind: .custom(CustomInfo(
            title: "Dinner at Joe's",
            icon: ItemCategory.restaurant.icon,
            time: nil,
            latitude: 42.3601,
            longitude: -71.0589,
            address: "123 Main St, Boston, MA"
        ))
    )

    return QuickAddItemSheet(
        tripId: existing.tripId,
        day: existing.day,
        existingItem: existing
    ) { item in
        print("Updated: \(item)")
    }
}
