namespace Theriapolis.Core.Time;

public enum Season : byte { Spring, Summer, Autumn, Winter }

/// <summary>
/// Single in-game time counter. Measured in whole seconds so it serializes
/// trivially and stays deterministic — no floating-point drift over a long
/// playthrough.
///
/// Phase 4 callers advance the clock from world-map travel and tactical
/// stepping. Phase 8 weather/seasons reads from it.
/// </summary>
public sealed class WorldClock
{
    /// <summary>In-game seconds since world creation. Game time, not real time.</summary>
    public long InGameSeconds { get; private set; }

    // Calendar constants. A 96-day year (24 days × 4 seasons) keeps the math
    // tight; a real-world year would mean each season is a 90-hour playthrough.
    public const int SecondsPerMinute = 60;
    public const int SecondsPerHour   = 3600;
    public const int SecondsPerDay    = SecondsPerHour * 24;
    public const int DaysPerSeason    = 24;
    public const int DaysPerYear      = DaysPerSeason * 4;

    public int Day      => (int)(InGameSeconds / SecondsPerDay);
    public int Hour     => (int)((InGameSeconds % SecondsPerDay) / SecondsPerHour);
    public int Minute   => (int)((InGameSeconds % SecondsPerHour) / SecondsPerMinute);
    public int Year     => Day / DaysPerYear;
    public Season Season => (Season)((Day / DaysPerSeason) % 4);

    public void Advance(long seconds)
    {
        if (seconds < 0) throw new ArgumentOutOfRangeException(nameof(seconds));
        InGameSeconds += seconds;
    }

    public WorldClockState CaptureState() => new() { InGameSeconds = InGameSeconds };
    public void RestoreState(WorldClockState s) => InGameSeconds = s.InGameSeconds;

    /// <summary>Pretty-print like "Y0 Spring D5 14:23".</summary>
    public string Format() => $"Y{Year} {Season} D{Day % DaysPerSeason} {Hour:D2}:{Minute:D2}";
}

public sealed class WorldClockState
{
    public long InGameSeconds;
}
