//
//  AchievementDefinitions.swift
//  SportsTime
//
//  Registry of all achievement types and their requirements.
//

import Foundation
import SwiftUI

// MARK: - Achievement Category

enum AchievementCategory: String, Codable, CaseIterable {
    case count         // Milestone counts (1, 5, 10, etc.)
    case division      // Complete a division
    case conference    // Complete a conference
    case league        // Complete entire league
    case journey       // Special journey-based achievements
    case special       // Special one-off achievements

    var displayName: String {
        switch self {
        case .count: return "Milestones"
        case .division: return "Divisions"
        case .conference: return "Conferences"
        case .league: return "Leagues"
        case .journey: return "Journeys"
        case .special: return "Special"
        }
    }
}

// MARK: - Achievement Definition

struct AchievementDefinition: Identifiable, Hashable {
    let id: String
    let name: String
    let description: String
    let category: AchievementCategory
    let sport: Sport?           // nil for cross-sport achievements
    let iconName: String
    let iconColor: Color
    let requirement: AchievementRequirement
    let sortOrder: Int

    // Optional division/conference reference
    let divisionId: String?
    let conferenceId: String?

    init(
        id: String,
        name: String,
        description: String,
        category: AchievementCategory,
        sport: Sport? = nil,
        iconName: String,
        iconColor: Color,
        requirement: AchievementRequirement,
        sortOrder: Int = 0,
        divisionId: String? = nil,
        conferenceId: String? = nil
    ) {
        self.id = id
        self.name = name
        self.description = description
        self.category = category
        self.sport = sport
        self.iconName = iconName
        self.iconColor = iconColor
        self.requirement = requirement
        self.sortOrder = sortOrder
        self.divisionId = divisionId
        self.conferenceId = conferenceId
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }

    static func == (lhs: AchievementDefinition, rhs: AchievementDefinition) -> Bool {
        lhs.id == rhs.id
    }
}

// MARK: - Achievement Requirement

enum AchievementRequirement: Hashable {
    case visitCount(Int)                      // Visit N unique stadiums
    case visitCountForSport(Int, Sport)       // Visit N stadiums for a specific sport
    case completeDivision(String)             // Complete all stadiums in a division
    case completeConference(String)           // Complete all stadiums in a conference
    case completeLeague(Sport)                // Complete all stadiums in a league
    case visitsInDays(Int, days: Int)         // Visit N stadiums within N days
    case multipleLeagues(Int)                 // Visit stadiums from N different leagues
    case firstVisit                           // First stadium visit ever
    case specificStadium(String)              // Visit a specific stadium
}

// MARK: - Achievement Registry

enum AchievementRegistry {

    // MARK: - All Definitions

    /// All achievement definitions sorted by category and sort order
    static let all: [AchievementDefinition] = {
        var definitions: [AchievementDefinition] = []
        definitions.append(contentsOf: countAchievements)
        definitions.append(contentsOf: mlbDivisionAchievements)
        definitions.append(contentsOf: mlbConferenceAchievements)
        definitions.append(contentsOf: nbaDivisionAchievements)
        definitions.append(contentsOf: nbaConferenceAchievements)
        definitions.append(contentsOf: nhlDivisionAchievements)
        definitions.append(contentsOf: nhlConferenceAchievements)
        definitions.append(contentsOf: leagueAchievements)
        definitions.append(contentsOf: journeyAchievements)
        definitions.append(contentsOf: specialAchievements)
        return definitions.sorted { $0.sortOrder < $1.sortOrder }
    }()

    // MARK: - Count Achievements

    static let countAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "first_visit",
            name: "First Pitch",
            description: "Visit your first stadium",
            category: .count,
            iconName: "1.circle.fill",
            iconColor: .green,
            requirement: .firstVisit,
            sortOrder: 100
        ),
        AchievementDefinition(
            id: "count_5",
            name: "Getting Started",
            description: "Visit 5 different stadiums",
            category: .count,
            iconName: "5.circle.fill",
            iconColor: .blue,
            requirement: .visitCount(5),
            sortOrder: 101
        ),
        AchievementDefinition(
            id: "count_10",
            name: "Double Digits",
            description: "Visit 10 different stadiums",
            category: .count,
            iconName: "10.circle.fill",
            iconColor: .orange,
            requirement: .visitCount(10),
            sortOrder: 102
        ),
        AchievementDefinition(
            id: "count_20",
            name: "Veteran Fan",
            description: "Visit 20 different stadiums",
            category: .count,
            iconName: "20.circle.fill",
            iconColor: .purple,
            requirement: .visitCount(20),
            sortOrder: 103
        ),
        AchievementDefinition(
            id: "count_30",
            name: "Stadium Enthusiast",
            description: "Visit 30 different stadiums",
            category: .count,
            iconName: "30.circle.fill",
            iconColor: .red,
            requirement: .visitCount(30),
            sortOrder: 104
        ),
        AchievementDefinition(
            id: "count_50",
            name: "Road Warrior",
            description: "Visit 50 different stadiums",
            category: .count,
            iconName: "50.circle.fill",
            iconColor: .yellow,
            requirement: .visitCount(50),
            sortOrder: 105
        ),
        AchievementDefinition(
            id: "count_75",
            name: "Stadium Expert",
            description: "Visit 75 different stadiums",
            category: .count,
            iconName: "75.circle.fill",
            iconColor: .mint,
            requirement: .visitCount(75),
            sortOrder: 106
        ),
        AchievementDefinition(
            id: "count_all",
            name: "Stadium Master",
            description: "Visit all 92 MLB, NBA, and NHL stadiums",
            category: .count,
            iconName: "star.circle.fill",
            iconColor: .yellow,
            requirement: .visitCount(92),
            sortOrder: 107
        )
    ]

    // MARK: - MLB Division Achievements

    static let mlbDivisionAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "mlb_al_east_complete",
            name: "AL East Champion",
            description: "Visit all AL East stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_al_east"),
            sortOrder: 200,
            divisionId: "mlb_al_east"
        ),
        AchievementDefinition(
            id: "mlb_al_central_complete",
            name: "AL Central Champion",
            description: "Visit all AL Central stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_al_central"),
            sortOrder: 201,
            divisionId: "mlb_al_central"
        ),
        AchievementDefinition(
            id: "mlb_al_west_complete",
            name: "AL West Champion",
            description: "Visit all AL West stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_al_west"),
            sortOrder: 202,
            divisionId: "mlb_al_west"
        ),
        AchievementDefinition(
            id: "mlb_nl_east_complete",
            name: "NL East Champion",
            description: "Visit all NL East stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_nl_east"),
            sortOrder: 203,
            divisionId: "mlb_nl_east"
        ),
        AchievementDefinition(
            id: "mlb_nl_central_complete",
            name: "NL Central Champion",
            description: "Visit all NL Central stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_nl_central"),
            sortOrder: 204,
            divisionId: "mlb_nl_central"
        ),
        AchievementDefinition(
            id: "mlb_nl_west_complete",
            name: "NL West Champion",
            description: "Visit all NL West stadiums",
            category: .division,
            sport: .mlb,
            iconName: "baseball.fill",
            iconColor: .red,
            requirement: .completeDivision("mlb_nl_west"),
            sortOrder: 205,
            divisionId: "mlb_nl_west"
        )
    ]

    // MARK: - MLB Conference Achievements

    static let mlbConferenceAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "mlb_al_complete",
            name: "American League Complete",
            description: "Visit all American League stadiums",
            category: .conference,
            sport: .mlb,
            iconName: "baseball.circle.fill",
            iconColor: .red,
            requirement: .completeConference("mlb_al"),
            sortOrder: 300,
            conferenceId: "mlb_al"
        ),
        AchievementDefinition(
            id: "mlb_nl_complete",
            name: "National League Complete",
            description: "Visit all National League stadiums",
            category: .conference,
            sport: .mlb,
            iconName: "baseball.circle.fill",
            iconColor: .red,
            requirement: .completeConference("mlb_nl"),
            sortOrder: 301,
            conferenceId: "mlb_nl"
        )
    ]

    // MARK: - NBA Division Achievements

    static let nbaDivisionAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "nba_atlantic_complete",
            name: "Atlantic Division Champion",
            description: "Visit all Atlantic Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_atlantic"),
            sortOrder: 210,
            divisionId: "nba_atlantic"
        ),
        AchievementDefinition(
            id: "nba_central_complete",
            name: "Central Division Champion",
            description: "Visit all Central Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_central"),
            sortOrder: 211,
            divisionId: "nba_central"
        ),
        AchievementDefinition(
            id: "nba_southeast_complete",
            name: "Southeast Division Champion",
            description: "Visit all Southeast Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_southeast"),
            sortOrder: 212,
            divisionId: "nba_southeast"
        ),
        AchievementDefinition(
            id: "nba_northwest_complete",
            name: "Northwest Division Champion",
            description: "Visit all Northwest Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_northwest"),
            sortOrder: 213,
            divisionId: "nba_northwest"
        ),
        AchievementDefinition(
            id: "nba_pacific_complete",
            name: "Pacific Division Champion",
            description: "Visit all Pacific Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_pacific"),
            sortOrder: 214,
            divisionId: "nba_pacific"
        ),
        AchievementDefinition(
            id: "nba_southwest_complete",
            name: "Southwest Division Champion",
            description: "Visit all Southwest Division arenas",
            category: .division,
            sport: .nba,
            iconName: "basketball.fill",
            iconColor: .orange,
            requirement: .completeDivision("nba_southwest"),
            sortOrder: 215,
            divisionId: "nba_southwest"
        )
    ]

    // MARK: - NBA Conference Achievements

    static let nbaConferenceAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "nba_eastern_complete",
            name: "Eastern Conference Complete",
            description: "Visit all Eastern Conference arenas",
            category: .conference,
            sport: .nba,
            iconName: "basketball.circle.fill",
            iconColor: .orange,
            requirement: .completeConference("nba_eastern"),
            sortOrder: 310,
            conferenceId: "nba_eastern"
        ),
        AchievementDefinition(
            id: "nba_western_complete",
            name: "Western Conference Complete",
            description: "Visit all Western Conference arenas",
            category: .conference,
            sport: .nba,
            iconName: "basketball.circle.fill",
            iconColor: .orange,
            requirement: .completeConference("nba_western"),
            sortOrder: 311,
            conferenceId: "nba_western"
        )
    ]

    // MARK: - NHL Division Achievements

    static let nhlDivisionAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "nhl_atlantic_complete",
            name: "NHL Atlantic Champion",
            description: "Visit all Atlantic Division arenas",
            category: .division,
            sport: .nhl,
            iconName: "hockey.puck.fill",
            iconColor: .blue,
            requirement: .completeDivision("nhl_atlantic"),
            sortOrder: 220,
            divisionId: "nhl_atlantic"
        ),
        AchievementDefinition(
            id: "nhl_metropolitan_complete",
            name: "Metropolitan Champion",
            description: "Visit all Metropolitan Division arenas",
            category: .division,
            sport: .nhl,
            iconName: "hockey.puck.fill",
            iconColor: .blue,
            requirement: .completeDivision("nhl_metropolitan"),
            sortOrder: 221,
            divisionId: "nhl_metropolitan"
        ),
        AchievementDefinition(
            id: "nhl_central_complete",
            name: "NHL Central Champion",
            description: "Visit all Central Division arenas",
            category: .division,
            sport: .nhl,
            iconName: "hockey.puck.fill",
            iconColor: .blue,
            requirement: .completeDivision("nhl_central"),
            sortOrder: 222,
            divisionId: "nhl_central"
        ),
        AchievementDefinition(
            id: "nhl_pacific_complete",
            name: "NHL Pacific Champion",
            description: "Visit all Pacific Division arenas",
            category: .division,
            sport: .nhl,
            iconName: "hockey.puck.fill",
            iconColor: .blue,
            requirement: .completeDivision("nhl_pacific"),
            sortOrder: 223,
            divisionId: "nhl_pacific"
        )
    ]

    // MARK: - NHL Conference Achievements

    static let nhlConferenceAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "nhl_eastern_complete",
            name: "NHL Eastern Conference Complete",
            description: "Visit all Eastern Conference arenas",
            category: .conference,
            sport: .nhl,
            iconName: "hockey.puck.circle.fill",
            iconColor: .blue,
            requirement: .completeConference("nhl_eastern"),
            sortOrder: 320,
            conferenceId: "nhl_eastern"
        ),
        AchievementDefinition(
            id: "nhl_western_complete",
            name: "NHL Western Conference Complete",
            description: "Visit all Western Conference arenas",
            category: .conference,
            sport: .nhl,
            iconName: "hockey.puck.circle.fill",
            iconColor: .blue,
            requirement: .completeConference("nhl_western"),
            sortOrder: 321,
            conferenceId: "nhl_western"
        )
    ]

    // MARK: - League Achievements

    static let leagueAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "mlb_complete",
            name: "Diamond Collector",
            description: "Visit all 30 MLB stadiums",
            category: .league,
            sport: .mlb,
            iconName: "diamond.fill",
            iconColor: .red,
            requirement: .completeLeague(.mlb),
            sortOrder: 400
        ),
        AchievementDefinition(
            id: "nba_complete",
            name: "Court Master",
            description: "Visit all 30 NBA arenas",
            category: .league,
            sport: .nba,
            iconName: "trophy.fill",
            iconColor: .orange,
            requirement: .completeLeague(.nba),
            sortOrder: 401
        ),
        AchievementDefinition(
            id: "nhl_complete",
            name: "Ice Warrior",
            description: "Visit all 32 NHL arenas",
            category: .league,
            sport: .nhl,
            iconName: "crown.fill",
            iconColor: .blue,
            requirement: .completeLeague(.nhl),
            sortOrder: 402
        )
    ]

    // MARK: - Journey Achievements

    static let journeyAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "journey_weekend_warrior",
            name: "Weekend Warrior",
            description: "Visit 3 stadiums in 3 days",
            category: .journey,
            iconName: "figure.run",
            iconColor: .green,
            requirement: .visitsInDays(3, days: 3),
            sortOrder: 500
        ),
        AchievementDefinition(
            id: "journey_road_trip",
            name: "Road Trip Champion",
            description: "Visit 5 stadiums in 7 days",
            category: .journey,
            iconName: "car.fill",
            iconColor: .cyan,
            requirement: .visitsInDays(5, days: 7),
            sortOrder: 501
        ),
        AchievementDefinition(
            id: "journey_marathon",
            name: "Stadium Marathon",
            description: "Visit 7 stadiums in 10 days",
            category: .journey,
            iconName: "flame.fill",
            iconColor: .orange,
            requirement: .visitsInDays(7, days: 10),
            sortOrder: 502
        ),
        AchievementDefinition(
            id: "journey_triple_threat",
            name: "Triple Threat",
            description: "Visit stadiums from all 3 leagues (MLB, NBA, NHL)",
            category: .journey,
            iconName: "star.fill",
            iconColor: .yellow,
            requirement: .multipleLeagues(3),
            sortOrder: 503
        )
    ]

    // MARK: - Special Achievements

    static let specialAchievements: [AchievementDefinition] = [
        AchievementDefinition(
            id: "special_fenway",
            name: "Green Monster",
            description: "Visit Fenway Park",
            category: .special,
            sport: .mlb,
            iconName: "building.columns.fill",
            iconColor: .green,
            requirement: .specificStadium("stadium_mlb_fenway_park"),
            sortOrder: 600
        ),
        AchievementDefinition(
            id: "special_wrigley",
            name: "Ivy League",
            description: "Visit Wrigley Field",
            category: .special,
            sport: .mlb,
            iconName: "leaf.fill",
            iconColor: .green,
            requirement: .specificStadium("stadium_mlb_wrigley_field"),
            sortOrder: 601
        ),
        AchievementDefinition(
            id: "special_msg",
            name: "World's Most Famous Arena",
            description: "Visit Madison Square Garden",
            category: .special,
            sport: .nba,
            iconName: "sparkles",
            iconColor: .orange,
            requirement: .specificStadium("stadium_nba_madison_square_garden"),
            sortOrder: 602
        )
    ]

    // MARK: - Lookup Methods

    /// Get achievement by ID
    static func achievement(byId id: String) -> AchievementDefinition? {
        all.first { $0.id == id }
    }

    /// Get achievements by category
    static func achievements(forCategory category: AchievementCategory) -> [AchievementDefinition] {
        all.filter { $0.category == category }
    }

    /// Get achievements for a sport
    static func achievements(forSport sport: Sport) -> [AchievementDefinition] {
        all.filter { $0.sport == sport || $0.sport == nil }
    }

    /// Get division achievements for a sport
    static func divisionAchievements(forSport sport: Sport) -> [AchievementDefinition] {
        all.filter { $0.sport == sport && $0.category == .division }
    }

    /// Get conference achievements for a sport
    static func conferenceAchievements(forSport sport: Sport) -> [AchievementDefinition] {
        all.filter { $0.sport == sport && $0.category == .conference }
    }
}
