using System.Text.Json.Serialization;
using Prospect.Server.Api.Services.Auth.Extensions;
using Prospect.Server.Api.Services.CloudScript;

public class RequestStoreRotationDataRequest
{
    // Empty request
}

public class StoreRotationData
{
    [JsonPropertyName("storeId")]
    public string StoreID { get; set; }
    [JsonPropertyName("expirationData")]
    public DateTime ExpirationData { get; set; }
}

public class RequestStoreRotationDataResponse
{
    [JsonPropertyName("dailyStoreData")]
    public StoreRotationData DailyStoreData { get; set; }
    [JsonPropertyName("weeklyStoreData")]
    public StoreRotationData WeeklyStoreData { get; set; }
    [JsonPropertyName("error")]
    public string Error { get; set; }
}

[CloudScriptFunction("RequestStoreRotationData")]
public class RequestStoreRotationDataFunction : ICloudScriptFunction<RequestStoreRotationDataRequest, RequestStoreRotationDataResponse>
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public RequestStoreRotationDataFunction(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    // Nombre de variantes de rotation (les storeId "DailyShop_N" / "WeeklyShop_N"
    // permettent au client de distinguer chaque rotation et de rafraîchir son cache).
    private const int DailyVariants = 8;
    private const int WeeklyVariants = 4;

    public async Task<RequestStoreRotationDataResponse> ExecuteAsync(RequestStoreRotationDataRequest request)
    {
        var context = _httpContextAccessor.HttpContext;
        if (context == null)
        {
            throw new CloudScriptException("CloudScript was not called within a http request");
        }

        var now = DateTime.UtcNow;

        // Rotation quotidienne : expire au prochain minuit UTC ; l'index de rotation
        // est le nombre de jours écoulés depuis l'epoch (déterministe, stable).
        var todayUtc = now.Date;
        var dailyExpiration = todayUtc.AddDays(1);
        var dayIndex = (int)(todayUtc - DateTime.UnixEpoch.Date).TotalDays;
        var dailyStoreId = $"DailyShop_{dayIndex % DailyVariants}";

        // Rotation hebdomadaire : expire au prochain lundi 00:00 UTC.
        // DayOfWeek : dimanche=0 ; on ramène lundi=0.
        var daysSinceMonday = ((int)todayUtc.DayOfWeek + 6) % 7;
        var weekStart = todayUtc.AddDays(-daysSinceMonday);
        var weeklyExpiration = weekStart.AddDays(7);
        var weekIndex = (int)Math.Floor((weekStart - DateTime.UnixEpoch.Date).TotalDays / 7);
        var weeklyStoreId = $"WeeklyShop_{weekIndex % WeeklyVariants}";

        return new RequestStoreRotationDataResponse
        {
            Error = "",
            DailyStoreData = new StoreRotationData {
                StoreID = dailyStoreId,
                ExpirationData = dailyExpiration
            },
            WeeklyStoreData = new StoreRotationData {
                StoreID = weeklyStoreId,
                ExpirationData = weeklyExpiration
            }
        };
    }
}
