//
//  PhotoImportViewModel.swift
//  SportsTime
//
//  ViewModel for photo import flow - orchestrates extraction, matching, and import.
//

import Foundation
import SwiftUI
import PhotosUI
import SwiftData
import Photos

@MainActor @Observable
final class PhotoImportViewModel {
    // State
    var showingPicker = false
    var isProcessing = false
    var processedCount = 0
    var totalCount = 0

    // Results
    var processedPhotos: [PhotoImportCandidate] = []
    var confirmedImports: Set<UUID> = []
    var selectedMatches: [UUID: GameMatchCandidate] = [:]

    // Services
    private let metadataExtractor = PhotoMetadataExtractor.shared
    private let gameMatcher = GameMatcher.shared

    // MARK: - Computed

    var categorized: GameMatcher.CategorizedImports {
        gameMatcher.categorizeImports(processedPhotos)
    }

    var hasConfirmedImports: Bool {
        !confirmedImports.isEmpty
    }

    var confirmedCount: Int {
        confirmedImports.count
    }

    // MARK: - Photo Processing

    func processSelectedPhotos(_ items: [PhotosPickerItem]) async {
        guard !items.isEmpty else { return }

        isProcessing = true
        totalCount = items.count
        processedCount = 0
        processedPhotos = []
        confirmedImports = []
        selectedMatches = [:]

        // Load PHAssets from PhotosPickerItems
        var assets: [PHAsset] = []

        for item in items {
            if let assetId = item.itemIdentifier {
                let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil)
                if let asset = fetchResult.firstObject {
                    assets.append(asset)
                }
            }
            processedCount += 1
        }

        // Extract metadata from all assets
        let metadataList = await metadataExtractor.extractMetadata(from: assets)

        // Process each photo through game matcher
        processedCount = 0
        for metadata in metadataList {
            let candidate = await gameMatcher.processPhotoForImport(metadata: metadata)
            processedPhotos.append(candidate)

            // Auto-confirm high-confidence matches
            if candidate.canAutoProcess {
                confirmedImports.insert(candidate.id)
            }

            processedCount += 1
        }

        isProcessing = false
    }

    // MARK: - User Actions

    func toggleConfirmation(for candidateId: UUID) {
        if confirmedImports.contains(candidateId) {
            confirmedImports.remove(candidateId)
        } else {
            confirmedImports.insert(candidateId)
        }
    }

    func selectMatch(_ match: GameMatchCandidate, for candidateId: UUID) {
        selectedMatches[candidateId] = match
        confirmedImports.insert(candidateId)
    }

    func confirmAll() {
        for candidate in processedPhotos {
            if case .singleMatch = candidate.matchResult {
                confirmedImports.insert(candidate.id)
            } else if case .multipleMatches = candidate.matchResult,
                      selectedMatches[candidate.id] != nil {
                confirmedImports.insert(candidate.id)
            }
        }
    }

    // MARK: - Import Creation

    func createVisits(modelContext: ModelContext) async {
        for candidate in processedPhotos {
            guard confirmedImports.contains(candidate.id) else { continue }

            // Get the match to use
            let matchToUse: GameMatchCandidate?

            switch candidate.matchResult {
            case .singleMatch(let match):
                matchToUse = match
            case .multipleMatches:
                matchToUse = selectedMatches[candidate.id]
            case .noMatches:
                matchToUse = nil
            }

            guard let match = matchToUse else { continue }

            // Create the visit
            let visit = StadiumVisit(
                canonicalStadiumId: match.stadium.id.uuidString,
                stadiumUUID: match.stadium.id,
                stadiumNameAtVisit: match.stadium.name,
                visitDate: match.game.dateTime,
                sport: match.game.sport,
                visitType: .game,
                homeTeamName: match.homeTeam.fullName,
                awayTeamName: match.awayTeam.fullName,
                finalScore: nil,
                scoreSource: nil,
                dataSource: .automatic,
                seatLocation: nil,
                notes: nil,
                photoLatitude: candidate.metadata.coordinates?.latitude,
                photoLongitude: candidate.metadata.coordinates?.longitude,
                photoCaptureDate: candidate.metadata.captureDate,
                source: .photoImport
            )

            modelContext.insert(visit)
        }

        try? modelContext.save()
    }

    // MARK: - Reset

    func reset() {
        processedPhotos = []
        confirmedImports = []
        selectedMatches = [:]
        isProcessing = false
        processedCount = 0
        totalCount = 0
    }
}
