//
// NHLDataCache.swift
// IceGlass
//
// Copyright 2026 Rouslan Zenetl. All Rights Reserved.
//

import Foundation

/// Snapshot of API state persisted between app launches so cold-launch shows
/// last-known data with an "as-of" timestamp instead of an empty page.
struct CachedSnapshot: Codable, Sendable {
    let lastUpdated: Date
    let scoreboard: Scoreboard?
    let standings: Standings?
    let bracket: PlayoffBracket?
}

/// Single-file Codable cache in Application Support. Atomic writes; fail-soft
/// reads — corrupt or version-mismatched payloads return nil and the next
/// fetch overwrites with fresh data.
actor NHLDataCache {
    private let logger = IceGlassLogger(
        subsystem: Bundle.main.bundleIdentifier ?? "dev.rzen.indie.IceGlass",
        category: "NHLDataCache"
    )

    private let fileURL: URL

    init(filename: String = "nhl-snapshot.json") {
        let fm = FileManager.default
        let supportDir = (try? fm.url(
            for: .applicationSupportDirectory,
            in: .userDomainMask,
            appropriateFor: nil,
            create: true
        )) ?? fm.temporaryDirectory

        let bundleId = Bundle.main.bundleIdentifier ?? "dev.rzen.indie.IceGlass"
        let appDir = supportDir.appendingPathComponent(bundleId, isDirectory: true)
        try? fm.createDirectory(at: appDir, withIntermediateDirectories: true)
        self.fileURL = appDir.appendingPathComponent(filename)
    }

    func load() -> CachedSnapshot? {
        guard FileManager.default.fileExists(atPath: fileURL.path) else { return nil }
        do {
            let data = try Data(contentsOf: fileURL)
            let decoder = JSONDecoder()
            decoder.dateDecodingStrategy = .iso8601
            return try decoder.decode(CachedSnapshot.self, from: data)
        } catch {
            logger.warning("Cache load failed (will refetch): \(error.localizedDescription)")
            return nil
        }
    }

    func save(_ snapshot: CachedSnapshot) {
        do {
            let encoder = JSONEncoder()
            encoder.dateEncodingStrategy = .iso8601
            let data = try encoder.encode(snapshot)
            try data.write(to: fileURL, options: .atomic)
        } catch {
            logger.error("Cache save failed: \(error.localizedDescription)")
        }
    }
}
