//
//  SyncStatusMonitor.swift
//  SportsTime
//
//  In-memory sync status tracking for debug builds.
//  Shows per-entity sync status in Settings.
//

import Foundation

#if DEBUG

// MARK: - Entity Types

enum SyncEntityType: String, CaseIterable, Identifiable {
    case stadium = "Stadium"
    case leagueStructure = "League Structure"
    case team = "Team"
    case teamAlias = "Team Alias"
    case stadiumAlias = "Stadium Alias"
    case game = "Game"
    case sport = "Sport"

    var id: String { rawValue }

    var iconName: String {
        switch self {
        case .stadium: return "building.2"
        case .leagueStructure: return "list.bullet.indent"
        case .team: return "person.3"
        case .teamAlias: return "person.text.rectangle"
        case .stadiumAlias: return "building"
        case .game: return "sportscourt"
        case .sport: return "figure.run"
        }
    }
}

// MARK: - Entity Sync Status

struct EntitySyncStatus: Identifiable {
    let id: SyncEntityType
    let entityType: SyncEntityType
    let lastSyncTime: Date?
    let isSuccess: Bool
    let recordCount: Int
    let errorMessage: String?
    let duration: TimeInterval?

    init(
        entityType: SyncEntityType,
        lastSyncTime: Date? = nil,
        isSuccess: Bool = false,
        recordCount: Int = 0,
        errorMessage: String? = nil,
        duration: TimeInterval? = nil
    ) {
        self.id = entityType
        self.entityType = entityType
        self.lastSyncTime = lastSyncTime
        self.isSuccess = isSuccess
        self.recordCount = recordCount
        self.errorMessage = errorMessage
        self.duration = duration
    }

    /// Status that hasn't been synced yet
    static func pending(_ entityType: SyncEntityType) -> EntitySyncStatus {
        EntitySyncStatus(entityType: entityType)
    }
}

// MARK: - Sync Status Monitor

@MainActor
@Observable
final class SyncStatusMonitor {
    static let shared = SyncStatusMonitor()

    private(set) var entityStatuses: [SyncEntityType: EntitySyncStatus] = [:]
    private(set) var overallSyncInProgress: Bool = false
    private(set) var lastFullSyncTime: Date?
    private(set) var lastFullSyncDuration: TimeInterval?

    private init() {
        // Initialize all entities with pending status
        for entityType in SyncEntityType.allCases {
            entityStatuses[entityType] = .pending(entityType)
        }
    }

    // MARK: - Status Updates

    /// Called when a full sync cycle begins
    func syncStarted() {
        overallSyncInProgress = true
    }

    /// Called after each entity sync completes
    func updateEntityStatus(
        _ entityType: SyncEntityType,
        success: Bool,
        recordCount: Int,
        duration: TimeInterval,
        errorMessage: String? = nil
    ) {
        entityStatuses[entityType] = EntitySyncStatus(
            entityType: entityType,
            lastSyncTime: Date(),
            isSuccess: success,
            recordCount: recordCount,
            errorMessage: errorMessage,
            duration: duration
        )
    }

    /// Called when the full sync cycle completes
    func syncCompleted(totalDuration: TimeInterval) {
        overallSyncInProgress = false
        lastFullSyncTime = Date()
        lastFullSyncDuration = totalDuration
    }

    /// Called when sync fails before completing
    func syncFailed(error: Error) {
        overallSyncInProgress = false
    }

    // MARK: - Computed Properties

    /// All entity statuses in sync order
    var orderedStatuses: [EntitySyncStatus] {
        SyncEntityType.allCases.compactMap { entityStatuses[$0] }
    }

    /// Whether all synced entities succeeded
    var allSuccessful: Bool {
        entityStatuses.values.allSatisfy { $0.isSuccess || $0.lastSyncTime == nil }
    }

    /// Count of entities that failed
    var failedCount: Int {
        entityStatuses.values.filter { !$0.isSuccess && $0.lastSyncTime != nil }.count
    }

    /// Total records synced across all entities
    var totalRecordsSynced: Int {
        entityStatuses.values.reduce(0) { $0 + $1.recordCount }
    }
}

#endif
