//
//  GameManager.swift
//  MagicCounter
//
//  Created by Atridad Lahiji on 2025-12-06.
//

import Foundation
import SwiftUI
import Combine

/**
 * Manages the global game state and match history.
 *
 * - matchHistory: List of all past and current matches.
 * - activeMatch: The currently active match, if any.
 */
@MainActor
final class GameManager: ObservableObject {
    @Published var matchHistory: [MatchRecord] = []
    @Published var activeMatch: MatchRecord?
    
    private let historyKey = "match_history_json"
    private let saveSubject = PassthroughSubject<Void, Never>()
    private var cancellables = Set<AnyCancellable>()
    
    nonisolated init() {
        Task { @MainActor in
            self.loadHistory()
            self.setupAutoSave()
        }
    }
    
    private func setupAutoSave() {
        saveSubject
            .debounce(for: .seconds(1), scheduler: RunLoop.main)
            .sink { [weak self] _ in
                self?.saveHistory()
            }
            .store(in: &cancellables)
    }
    
    func startNewGame(players: [String], startingLife: Int, trackPoison: Bool, trackCommander: Bool, matchName: String) {
        let playerStates = players.enumerated().map { (index, name) in
            PlayerState(
                id: index,
                name: name,
                life: startingLife,
                poison: 0,
                commanderDamages: [:],
                scooped: false
            )
        }
        
        let gameState = GameState(
            players: playerStates,
            startingLife: startingLife,
            trackPoison: trackPoison,
            trackCommanderDamage: trackCommander,
            stopped: false
        )
        
        let newMatch = MatchRecord(
            id: UUID().uuidString,
            name: matchName.isEmpty ? "Match \(Date().formatted())" : matchName,
            startedAt: Date(),
            lastUpdated: Date(),
            ongoing: true,
            winnerPlayerId: nil,
            state: gameState
        )
        
        activeMatch = newMatch
        matchHistory.insert(newMatch, at: 0)
        saveHistory()
    }
    
    func updateActiveGame(state: GameState) {
        guard var match = activeMatch else { return }
        match.state = state
        match.lastUpdated = Date()
        
        if state.stopped {
            match.ongoing = false
        } else if let winner = state.winner {
            match.ongoing = false
            match.winnerPlayerId = winner.id
        } else {
            match.ongoing = true
            match.winnerPlayerId = nil
        }
        
        activeMatch = match
        if let index = matchHistory.firstIndex(where: { $0.id == match.id }) {
            matchHistory[index] = match
        }
        saveSubject.send()
    }
    
    func stopGame() {
        guard var match = activeMatch else { return }
        match.ongoing = false
        match.state.stopped = true
        activeMatch = nil
        
        if let index = matchHistory.firstIndex(where: { $0.id == match.id }) {
            matchHistory[index] = match
        }
        saveHistory()
    }
    
    func deleteMatch(id: String) {
        if activeMatch?.id == id {
            activeMatch = nil
        }
        matchHistory.removeAll { $0.id == id }
        saveHistory()
    }
    
    func resumeMatch(_ match: MatchRecord) {
        activeMatch = match
    }
    
    private func loadHistory() {
        if let data = UserDefaults.standard.data(forKey: historyKey) {
            if let decoded = try? JSONDecoder().decode([MatchRecord].self, from: data) {
                matchHistory = decoded
            }
        }
    }
    
    private func saveHistory() {
        if let encoded = try? JSONEncoder().encode(matchHistory) {
            UserDefaults.standard.set(encoded, forKey: historyKey)
        }
    }
}
