//
//  ProgressViewModel.swift
//  SportsTime
//
//  ViewModel for stadium progress tracking and visualization.
//

import Foundation
import SwiftUI
import SwiftData

@MainActor
@Observable
final class ProgressViewModel {

    // MARK: - State

    var selectedSport: Sport = .mlb
    var isLoading = false
    var error: Error?
    var errorMessage: String?

    // MARK: - Data

    private(set) var visits: [StadiumVisit] = []
    private(set) var stadiums: [Stadium] = []
    private(set) var teams: [Team] = []

    // MARK: - Dependencies

    private var modelContainer: ModelContainer?
    private let dataProvider = AppDataProvider.shared

    // MARK: - Computed Properties

    /// Overall progress for the selected sport
    var leagueProgress: LeagueProgress {
        // Filter stadiums by sport directly (same as sportStadiums)
        let sportStadiums = stadiums.filter { $0.sport == selectedSport }

        let visitedStadiumIds = Set(
            visits
                .filter { $0.sportEnum == selectedSport }
                .compactMap { visit -> UUID? in
                    // Match visit's canonical stadium ID to a stadium
                    stadiums.first { stadium in
                        stadium.id == visit.stadiumUUID
                    }?.id
                }
        )

        let visited = sportStadiums.filter { visitedStadiumIds.contains($0.id) }
        let remaining = sportStadiums.filter { !visitedStadiumIds.contains($0.id) }

        return LeagueProgress(
            sport: selectedSport,
            totalStadiums: sportStadiums.count,
            visitedStadiums: visited.count,
            stadiumsVisited: visited,
            stadiumsRemaining: remaining
        )
    }

    /// Stadium visit status indexed by stadium ID
    var stadiumVisitStatus: [UUID: StadiumVisitStatus] {
        var statusMap: [UUID: StadiumVisitStatus] = [:]

        // Group visits by stadium
        let visitsByStadium = Dictionary(grouping: visits.filter { $0.sportEnum == selectedSport }) { $0.stadiumUUID }

        for stadium in stadiums {
            if let stadiumVisits = visitsByStadium[stadium.id], !stadiumVisits.isEmpty {
                let summaries = stadiumVisits.map { visit in
                    VisitSummary(
                        id: visit.id,
                        stadium: stadium,
                        visitDate: visit.visitDate,
                        visitType: visit.visitType,
                        sport: selectedSport,
                        matchup: visit.matchupDescription,
                        score: visit.finalScore,
                        photoCount: visit.photoMetadata?.count ?? 0,
                        notes: visit.notes
                    )
                }
                statusMap[stadium.id] = .visited(visits: summaries)
            } else {
                statusMap[stadium.id] = .notVisited
            }
        }

        return statusMap
    }

    /// Stadiums for the selected sport
    var sportStadiums: [Stadium] {
        stadiums.filter { $0.sport == selectedSport }
    }

    /// Visited stadiums for the selected sport
    var visitedStadiums: [Stadium] {
        leagueProgress.stadiumsVisited
    }

    /// Unvisited stadiums for the selected sport
    var unvisitedStadiums: [Stadium] {
        leagueProgress.stadiumsRemaining
    }

    /// Recent visits sorted by date
    var recentVisits: [VisitSummary] {
        visits
            .sorted { $0.visitDate > $1.visitDate }
            .prefix(10)
            .compactMap { visit -> VisitSummary? in
                guard let stadium = stadiums.first(where: { $0.id == visit.stadiumUUID }),
                      let sport = visit.sportEnum else {
                    return nil
                }
                return VisitSummary(
                    id: visit.id,
                    stadium: stadium,
                    visitDate: visit.visitDate,
                    visitType: visit.visitType,
                    sport: sport,
                    matchup: visit.matchupDescription,
                    score: visit.finalScore,
                    photoCount: visit.photoMetadata?.count ?? 0,
                    notes: visit.notes
                )
            }
    }

    // MARK: - Configuration

    func configure(with container: ModelContainer) {
        self.modelContainer = container
    }

    // MARK: - Actions

    func loadData() async {
        isLoading = true
        error = nil
        errorMessage = nil

        do {
            // Load stadiums and teams from data provider
            if dataProvider.stadiums.isEmpty {
                await dataProvider.loadInitialData()
            }
            stadiums = dataProvider.stadiums
            teams = dataProvider.teams

            // Load visits from SwiftData
            if let container = modelContainer {
                let context = ModelContext(container)
                let descriptor = FetchDescriptor<StadiumVisit>(
                    sortBy: [SortDescriptor(\.visitDate, order: .reverse)]
                )
                visits = try context.fetch(descriptor)
            }
        } catch {
            self.error = error
            self.errorMessage = error.localizedDescription
        }

        isLoading = false
    }

    func selectSport(_ sport: Sport) {
        selectedSport = sport
    }

    func clearError() {
        error = nil
        errorMessage = nil
    }

    // MARK: - Visit Management

    func deleteVisit(_ visit: StadiumVisit) async throws {
        guard let container = modelContainer else { return }

        let context = ModelContext(container)
        context.delete(visit)
        try context.save()

        // Reload data
        await loadData()
    }

    // MARK: - Progress Card Generation

    func progressCardData(includeUsername: Bool = false) -> ProgressCardData {
        ProgressCardData(
            sport: selectedSport,
            progress: leagueProgress,
            username: nil,
            includeMap: true,
            showDetailedStats: false
        )
    }
}
