//
//  PhotoImportView.swift
//  SportsTime
//
//  View for importing stadium visits from photos using GPS/date metadata.
//

import SwiftUI
import SwiftData
import PhotosUI
import Photos

// MARK: - Photo Import View

struct PhotoImportView: View {
    @Environment(\.modelContext) private var modelContext
    @Environment(\.colorScheme) private var colorScheme
    @Environment(\.dismiss) private var dismiss

    @State private var viewModel = PhotoImportViewModel()
    @State private var selectedPhotos: [PhotosPickerItem] = []
    @State private var showingPermissionAlert = false

    var body: some View {
        NavigationStack {
            Group {
                if viewModel.isProcessing {
                    processingView
                } else if viewModel.processedPhotos.isEmpty {
                    emptyStateView
                } else {
                    resultsView
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .themedBackground()
            .navigationTitle("Import from Photos")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                }

                if !viewModel.processedPhotos.isEmpty {
                    ToolbarItem(placement: .confirmationAction) {
                        Button("Import") {
                            importSelectedVisits()
                        }
                        .fontWeight(.semibold)
                        .disabled(!viewModel.hasConfirmedImports)
                    }
                }
            }
            .photosPicker(
                isPresented: $viewModel.showingPicker,
                selection: $selectedPhotos,
                maxSelectionCount: 20,
                matching: .images,
                photoLibrary: .shared()
            )
            .onChange(of: selectedPhotos) { _, newValue in
                Task {
                    await viewModel.processSelectedPhotos(newValue)
                }
            }
            .alert("Photo Library Access", isPresented: $showingPermissionAlert) {
                Button("Open Settings") {
                    if let url = URL(string: UIApplication.openSettingsURLString) {
                        UIApplication.shared.open(url)
                    }
                }
                Button("Cancel", role: .cancel) {}
            } message: {
                Text("SportsTime needs access to your photos to import stadium visits. Please enable access in Settings.")
            }
        }
    }

    // MARK: - Empty State

    private var emptyStateView: some View {
        VStack(spacing: Theme.Spacing.lg) {
            Spacer()

            // Icon
            ZStack {
                Circle()
                    .fill(Theme.warmOrange.opacity(0.15))
                    .frame(width: 120, height: 120)

                Image(systemName: "photo.on.rectangle.angled")
                    .font(.largeTitle)
                    .foregroundStyle(Theme.warmOrange)
            }

            VStack(spacing: Theme.Spacing.sm) {
                Text("Import from Photos")
                    .font(.title2)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                Text("Select photos taken at stadiums to automatically log your visits. We'll use GPS and date data to match them to games.")
                    .font(.body)
                    .foregroundStyle(Theme.textSecondary(colorScheme))
                    .multilineTextAlignment(.center)
                    .padding(.horizontal, Theme.Spacing.xl)
            }

            // Select Photos Button
            Button {
                checkPermissionsAndShowPicker()
            } label: {
                HStack {
                    Image(systemName: "photo.stack")
                    Text("Select Photos")
                }
                .font(.body)
                .foregroundStyle(.white)
                .frame(maxWidth: .infinity)
                .padding(Theme.Spacing.md)
                .background(Theme.warmOrange)
                .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
            }
            .padding(.horizontal, Theme.Spacing.xl)

            // Info card
            infoCard

            Spacer()
        }
        .padding(Theme.Spacing.md)
    }

    private var infoCard: some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
            HStack {
                Image(systemName: "info.circle.fill")
                    .foregroundStyle(Theme.warmOrange)
                    .accessibilityHidden(true)
                Text("How it works")
                    .font(.body)
            }

            VStack(alignment: .leading, spacing: Theme.Spacing.xs) {
                InfoRow(icon: "location.fill", text: "We read GPS location from your photos")
                InfoRow(icon: "calendar", text: "We match the date to scheduled games")
                InfoRow(icon: "checkmark.circle", text: "High confidence matches are auto-selected")
                InfoRow(icon: "hand.tap", text: "You confirm or edit the rest")
            }
        }
        .font(.subheadline)
        .foregroundStyle(Theme.textSecondary(colorScheme))
        .padding(Theme.Spacing.md)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
        .padding(.horizontal, Theme.Spacing.lg)
    }

    // MARK: - Processing View

    private var processingView: some View {
        VStack(spacing: Theme.Spacing.lg) {
            Spacer()

            LoadingSpinner(size: .large)

            VStack(spacing: Theme.Spacing.xs) {
                Text("Processing Photos")
                    .font(.headline)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                Text("\(viewModel.processedCount) of \(viewModel.totalCount)")
                    .font(.subheadline)
                    .foregroundStyle(Theme.textSecondary(colorScheme))
            }

            Spacer()
        }
    }

    // MARK: - Results View

    private var resultsView: some View {
        ScrollView {
            VStack(spacing: Theme.Spacing.lg) {
                // Summary header
                summaryHeader

                // Categorized results
                if !viewModel.categorized.autoProcessable.isEmpty {
                    resultSection(
                        title: "Auto-Matched",
                        subtitle: "High confidence matches",
                        icon: "checkmark.circle.fill",
                        color: .green,
                        candidates: viewModel.categorized.autoProcessable
                    )
                }

                if !viewModel.categorized.needsConfirmation.isEmpty {
                    resultSection(
                        title: "Needs Confirmation",
                        subtitle: "Please verify these matches",
                        icon: "questionmark.circle.fill",
                        color: Theme.warmOrange,
                        candidates: viewModel.categorized.needsConfirmation
                    )
                }

                if !viewModel.categorized.needsManualEntry.isEmpty {
                    resultSection(
                        title: "Manual Entry Required",
                        subtitle: "Could not auto-match these photos",
                        icon: "exclamationmark.triangle.fill",
                        color: .red,
                        candidates: viewModel.categorized.needsManualEntry
                    )
                }

                // Add more photos button
                Button {
                    viewModel.showingPicker = true
                } label: {
                    HStack {
                        Image(systemName: "plus.circle")
                        Text("Add More Photos")
                    }
                    .font(.body)
                    .foregroundStyle(Theme.warmOrange)
                }
                .padding(.top, Theme.Spacing.md)
            }
            .padding(Theme.Spacing.md)
        }
    }

    private var summaryHeader: some View {
        HStack(spacing: Theme.Spacing.md) {
            summaryBadge(
                count: viewModel.categorized.autoProcessable.count,
                label: "Auto",
                color: .green
            )

            summaryBadge(
                count: viewModel.categorized.needsConfirmation.count,
                label: "Confirm",
                color: Theme.warmOrange
            )

            summaryBadge(
                count: viewModel.categorized.needsManualEntry.count,
                label: "Manual",
                color: .red
            )
        }
        .padding(Theme.Spacing.md)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.medium))
    }

    private func summaryBadge(count: Int, label: String, color: Color) -> some View {
        VStack(spacing: 4) {
            Text("\(count)")
                .font(.title2)
                .foregroundStyle(color)

            Text(label)
                .font(.subheadline)
                .foregroundStyle(Theme.textSecondary(colorScheme))
        }
        .frame(maxWidth: .infinity)
    }

    private func resultSection(
        title: String,
        subtitle: String,
        icon: String,
        color: Color,
        candidates: [PhotoImportCandidate]
    ) -> some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
            // Section header
            HStack {
                Image(systemName: icon)
                    .foregroundStyle(color)
                VStack(alignment: .leading, spacing: 2) {
                    Text(title)
                        .font(.body)
                        .foregroundStyle(Theme.textPrimary(colorScheme))
                    Text(subtitle)
                        .font(.subheadline)
                        .foregroundStyle(Theme.textSecondary(colorScheme))
                }
                Spacer()
            }

            // Candidate cards
            ForEach(candidates) { candidate in
                PhotoImportCandidateCard(
                    candidate: candidate,
                    isConfirmed: viewModel.confirmedImports.contains(candidate.id),
                    onToggleConfirm: {
                        viewModel.toggleConfirmation(for: candidate.id)
                    },
                    onSelectMatch: { match in
                        viewModel.selectMatch(match, for: candidate.id)
                    }
                )
            }
        }
        .padding(Theme.Spacing.md)
        .background(Theme.cardBackground(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.large))
    }

    // MARK: - Actions

    private func checkPermissionsAndShowPicker() {
        Task {
            let status = await PhotoMetadataExtractor.shared.requestPhotoLibraryAccess()

            await MainActor.run {
                switch status {
                case .authorized, .limited:
                    viewModel.showingPicker = true
                case .denied, .restricted:
                    showingPermissionAlert = true
                default:
                    break
                }
            }
        }
    }

    private func importSelectedVisits() {
        Task {
            await viewModel.createVisits(modelContext: modelContext)
            dismiss()
        }
    }
}

// MARK: - Photo Import Candidate Card

struct PhotoImportCandidateCard: View {
    let candidate: PhotoImportCandidate
    let isConfirmed: Bool
    let onToggleConfirm: () -> Void
    let onSelectMatch: (GameMatchCandidate) -> Void

    @Environment(\.colorScheme) private var colorScheme
    @State private var showingMatchPicker = false

    var body: some View {
        VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
            // Photo date/location info
            HStack {
                if let date = candidate.metadata.captureDate {
                    Label(formatDate(date), systemImage: "calendar")
                }

                if let stadium = candidate.bestStadiumMatch {
                    Label(stadium.stadium.name, systemImage: "mappin")
                }

                Spacer()

                // Confirm toggle
                Button {
                    onToggleConfirm()
                } label: {
                    Image(systemName: isConfirmed ? "checkmark.circle.fill" : "circle")
                        .font(.title2)
                        .foregroundStyle(isConfirmed ? .green : Theme.textMuted(colorScheme))
                }
                .accessibilityLabel(isConfirmed ? "Deselect for import" : "Confirm import")
            }
            .font(.subheadline)
            .foregroundStyle(Theme.textSecondary(colorScheme))

            // Match result
            matchResultView
        }
        .padding(Theme.Spacing.sm)
        .background(Theme.cardBackgroundElevated(colorScheme))
        .clipShape(RoundedRectangle(cornerRadius: Theme.CornerRadius.small))
        .sheet(isPresented: $showingMatchPicker) {
            if case .multipleMatches(let matches) = candidate.matchResult {
                GameMatchPickerSheet(
                    matches: matches,
                    onSelect: { match in
                        onSelectMatch(match)
                        showingMatchPicker = false
                    }
                )
            }
        }
    }

    @ViewBuilder
    private var matchResultView: some View {
        switch candidate.matchResult {
        case .singleMatch(let match):
            matchRow(match)

        case .multipleMatches(let matches):
            Button {
                showingMatchPicker = true
            } label: {
                HStack {
                    VStack(alignment: .leading, spacing: 2) {
                        Text("\(matches.count) possible games")
                            .font(.body)
                            .foregroundStyle(Theme.textPrimary(colorScheme))
                        Text("Tap to select the correct game")
                            .font(.subheadline)
                            .foregroundStyle(Theme.warmOrange)
                    }
                    Spacer()
                    Image(systemName: "chevron.right")
                        .foregroundStyle(Theme.textMuted(colorScheme))
                        .accessibilityHidden(true)
                }
            }

        case .noMatches(let reason):
            HStack {
                Image(systemName: "exclamationmark.triangle")
                    .foregroundStyle(.red)
                    .accessibilityLabel("Error")
                Text(reason.description)
                    .font(.subheadline)
                    .foregroundStyle(Theme.textSecondary(colorScheme))
            }
        }
    }

    private func matchRow(_ match: GameMatchCandidate) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack {
                Text(match.fullMatchupDescription)
                    .font(.body)
                    .foregroundStyle(Theme.textPrimary(colorScheme))

                Image(systemName: match.game.sport.iconName)
                    .foregroundStyle(match.game.sport.themeColor)
            }

            Text("\(match.stadium.name) • \(match.gameDateTime)")
                .font(.subheadline)
                .foregroundStyle(Theme.textSecondary(colorScheme))

            // Confidence badge
            confidenceBadge(match.confidence.combined)
        }
    }

    private func confidenceBadge(_ confidence: CombinedConfidence) -> some View {
        let (text, color): (String, Color) = {
            switch confidence {
            case .autoSelect:
                return ("High confidence", .green)
            case .userConfirm:
                return ("Needs confirmation", Theme.warmOrange)
            case .manualOnly:
                return ("Low confidence", .red)
            }
        }()

        return Text(text)
            .font(.caption2)
            .foregroundStyle(color)
            .padding(.horizontal, 6)
            .padding(.vertical, 2)
            .background(color.opacity(0.15))
            .clipShape(Capsule())
    }

    private func formatDate(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        return formatter.string(from: date)
    }
}

// MARK: - Game Match Picker Sheet

struct GameMatchPickerSheet: View {
    let matches: [GameMatchCandidate]
    let onSelect: (GameMatchCandidate) -> Void

    @Environment(\.colorScheme) private var colorScheme
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            List(matches) { match in
                Button {
                    onSelect(match)
                } label: {
                    VStack(alignment: .leading, spacing: 4) {
                        HStack {
                            Text(match.fullMatchupDescription)
                                .font(.body)
                                .foregroundStyle(Theme.textPrimary(colorScheme))

                            Spacer()

                            Image(systemName: match.game.sport.iconName)
                                .foregroundStyle(match.game.sport.themeColor)
                        }

                        Text("\(match.stadium.name) • \(match.gameDateTime)")
                            .font(.subheadline)
                            .foregroundStyle(Theme.textSecondary(colorScheme))
                    }
                    .padding(.vertical, 4)
                }
            }
            .navigationTitle("Select Game")
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") {
                        dismiss()
                    }
                }
            }
        }
    }
}

// MARK: - Info Row

private struct InfoRow: View {
    let icon: String
    let text: String

    var body: some View {
        HStack(spacing: 8) {
            Image(systemName: icon)
                .frame(width: 16)
                .accessibilityHidden(true)
            Text(text)
        }
    }
}

// MARK: - Preview

#Preview {
    PhotoImportView()
        .modelContainer(for: StadiumVisit.self, inMemory: true)
}
