//
//  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 }

        print("📷 [PhotoImport] ════════════════════════════════════════════════")
        print("📷 [PhotoImport] Starting photo import with \(items.count) items")

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

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

        for (index, item) in items.enumerated() {
            print("📷 [PhotoImport] ────────────────────────────────────────────────")
            print("📷 [PhotoImport] Processing item \(index + 1)/\(items.count)")
            print("📷 [PhotoImport] Item identifier: \(item.itemIdentifier ?? "nil")")
            print("📷 [PhotoImport] Item supportedContentTypes: \(item.supportedContentTypes)")

            if let assetId = item.itemIdentifier {
                let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [assetId], options: nil)
                print("📷 [PhotoImport] PHAsset fetch result count: \(fetchResult.count)")

                if let asset = fetchResult.firstObject {
                    print("📷 [PhotoImport] ✅ Found PHAsset")
                    print("📷 [PhotoImport]   - localIdentifier: \(asset.localIdentifier)")
                    print("📷 [PhotoImport]   - mediaType: \(asset.mediaType.rawValue)")
                    print("📷 [PhotoImport]   - creationDate: \(asset.creationDate?.description ?? "nil")")
                    print("📷 [PhotoImport]   - location: \(asset.location?.description ?? "nil")")
                    print("📷 [PhotoImport]   - sourceType: \(asset.sourceType.rawValue)")
                    print("📷 [PhotoImport]   - pixelWidth: \(asset.pixelWidth)")
                    print("📷 [PhotoImport]   - pixelHeight: \(asset.pixelHeight)")
                    assets.append(asset)
                } else {
                    print("📷 [PhotoImport] ⚠️ No PHAsset found for identifier")
                }
            } else {
                print("📷 [PhotoImport] ⚠️ No itemIdentifier on PhotosPickerItem")
            }
            processedCount += 1
        }

        print("📷 [PhotoImport] ────────────────────────────────────────────────")
        print("📷 [PhotoImport] Loaded \(assets.count) PHAssets, extracting metadata...")

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

        print("📷 [PhotoImport] ────────────────────────────────────────────────")
        print("📷 [PhotoImport] Extracted \(metadataList.count) metadata records")

        // Summarize metadata extraction results
        let withLocation = metadataList.filter { $0.hasValidLocation }.count
        let withDate = metadataList.filter { $0.hasValidDate }.count
        print("📷 [PhotoImport] Photos with location: \(withLocation)/\(metadataList.count)")
        print("📷 [PhotoImport] Photos with date: \(withDate)/\(metadataList.count)")

        // Process each photo through game matcher
        processedCount = 0
        for (index, metadata) in metadataList.enumerated() {
            print("📷 [PhotoImport] Matching photo \(index + 1): date=\(metadata.captureDate?.description ?? "nil"), location=\(metadata.hasValidLocation)")
            let candidate = await gameMatcher.processPhotoForImport(metadata: metadata)
            processedPhotos.append(candidate)

            // Auto-confirm high-confidence matches
            if candidate.canAutoProcess {
                confirmedImports.insert(candidate.id)
                print("📷 [PhotoImport] ✅ Auto-confirmed match")
            }

            processedCount += 1
        }

        print("📷 [PhotoImport] ════════════════════════════════════════════════")
        print("📷 [PhotoImport] Import complete: \(processedPhotos.count) photos, \(confirmedImports.count) auto-confirmed")

        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(
                stadiumId: match.stadium.id,
                stadiumNameAtVisit: match.stadium.name,
                visitDate: match.game.dateTime,
                sport: match.game.sport,
                visitType: .game,
                gameId: match.game.id,
                homeTeamId: match.homeTeam.id,
                awayTeamId: match.awayTeam.id,
                homeTeamName: match.homeTeam.fullName,
                awayTeamName: match.awayTeam.fullName,
                finalScore: match.formattedFinalScore,
                scoreSource: match.formattedFinalScore != nil ? .scraped : 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
    }
}
