import Foundation

/// Frozen contract (plan §3.3). NON-SECRET per-host UI state only — anything
/// sensitive belongs in `KeychainHostStore` (§5.3 split: Keychain = secrets,
/// UserDefaults = prefs).
public protocol LastSessionStore: Sendable {
    func lastSessionId(host: UUID) -> UUID?
    func setLastSessionId(_ id: UUID?, host: UUID)
}

/// UserDefaults-backed implementation with an injectable suite for tests.
/// `@unchecked Sendable`: `UserDefaults` carries no Sendable annotation in
/// the SDK but is documented thread-safe ("NSUserDefaults is thread-safe"),
/// and this wrapper adds no mutable state of its own.
public struct UserDefaultsLastSessionStore: LastSessionStore, @unchecked Sendable {
    private static let keyPrefix = "lastSessionId."

    private let defaults: UserDefaults

    public init(defaults: UserDefaults = .standard) {
        self.defaults = defaults
    }

    public func lastSessionId(host: UUID) -> UUID? {
        guard let raw = defaults.string(forKey: Self.key(host)) else { return nil }
        // Stored value crosses a storage boundary — validate, never trust:
        // garbage reads back as nil instead of crashing or misrouting.
        return UUID(uuidString: raw)
    }

    public func setLastSessionId(_ id: UUID?, host: UUID) {
        guard let id else {
            defaults.removeObject(forKey: Self.key(host))
            return
        }
        defaults.set(id.uuidString, forKey: Self.key(host))
    }

    private static func key(_ host: UUID) -> String {
        keyPrefix + host.uuidString
    }
}
