import Foundation

/// Shades the activity grid by each day's **token usage** — the truest measure of how much work
/// a day actually saw — and falls back to **message count** for any day with no token data
/// (transcripts predating usage capture, or a backend that doesn't report it).
///
/// Tokens and messages live on wildly different magnitudes (thousands–millions vs. single
/// digits), so they can't share one scale: dropped into the same distribution, every
/// message-only day would collapse to near-black under the token range. Instead each metric is
/// normalized against *its own* ``ActivityScale``, and the per-day choice picks the matching
/// brightness — so a heavy token day and a heavy message-only day both read as a bright square,
/// each relative to its own kind of activity.
///
/// Pure and platform-agnostic, so the macOS host and the iPhone client shade their grids
/// identically (mirrors ``ActivityScale`` / ``StreakState``).
public struct ActivityShading: Sendable, Equatable {
    /// Brightness scale over days that recorded token usage.
    public let tokenScale: ActivityScale
    /// Brightness scale over message counts — the fallback for days without token data.
    public let messageScale: ActivityScale

    public init(
        tokensByDay: [Date: Int], messagesByDay: [Date: Int],
        floor: Double = ActivityScale.defaultFloor
    ) {
        self.tokenScale = ActivityScale(activityByDay: tokensByDay, floor: floor)
        self.messageScale = ActivityScale(activityByDay: messagesByDay, floor: floor)
    }

    /// Continuous brightness in `0…1` for a day: by its `tokens` when any were recorded,
    /// otherwise by its `messages`. A day with neither is `0` (the neutral empty-day gray).
    public func intensity(tokens: Int, messages: Int) -> Double {
        tokens > 0 ? tokenScale.intensity(for: tokens) : messageScale.intensity(for: messages)
    }
}
