namespace Apollinare.Domain.Entities;

/// <summary>
/// Tipo di abbonamento per un modulo
/// </summary>
public enum SubscriptionType
{
    /// <summary>Nessun abbonamento attivo</summary>
    None = 0,
    /// <summary>Abbonamento mensile</summary>
    Monthly = 1,
    /// <summary>Abbonamento annuale</summary>
    Annual = 2
}

/// <summary>
/// Rappresenta lo stato di abbonamento/attivazione di un modulo per questa istanza dell'applicazione.
/// Ogni ModuleSubscription è collegata 1:1 con un AppModule.
/// </summary>
public class ModuleSubscription : BaseEntity
{
    /// <summary>
    /// ID del modulo associato
    /// </summary>
    public int ModuleId { get; set; }

    /// <summary>
    /// Se true, il modulo è attualmente attivo e accessibile
    /// </summary>
    public bool IsEnabled { get; set; }

    /// <summary>
    /// Tipo di abbonamento corrente
    /// </summary>
    public SubscriptionType SubscriptionType { get; set; } = SubscriptionType.None;

    /// <summary>
    /// Data di inizio dell'abbonamento corrente
    /// </summary>
    public DateTime? StartDate { get; set; }

    /// <summary>
    /// Data di scadenza dell'abbonamento (null = nessuna scadenza, es. licenza perpetua)
    /// </summary>
    public DateTime? EndDate { get; set; }

    /// <summary>
    /// Se true, l'abbonamento si rinnova automaticamente alla scadenza
    /// </summary>
    public bool AutoRenew { get; set; }

    /// <summary>
    /// Note aggiuntive sull'abbonamento (es. codice ordine, riferimento contratto)
    /// </summary>
    public string? Notes { get; set; }

    /// <summary>
    /// Data dell'ultimo rinnovo effettuato
    /// </summary>
    public DateTime? LastRenewalDate { get; set; }

    /// <summary>
    /// Prezzo pagato per l'abbonamento corrente (può differire da BasePrice per sconti)
    /// </summary>
    public decimal? PaidPrice { get; set; }

    // Navigation property
    public AppModule Module { get; set; } = null!;

    /// <summary>
    /// Verifica se l'abbonamento è attualmente valido (attivo e non scaduto)
    /// </summary>
    public bool IsValid()
    {
        if (!IsEnabled)
            return false;

        // Se non c'è data di scadenza, è valido (licenza perpetua o core module)
        if (!EndDate.HasValue)
            return true;

        return EndDate.Value >= DateTime.UtcNow;
    }

    /// <summary>
    /// Calcola i giorni rimanenti alla scadenza (null se nessuna scadenza)
    /// </summary>
    public int? GetDaysRemaining()
    {
        if (!EndDate.HasValue)
            return null;

        var remaining = (EndDate.Value - DateTime.UtcNow).Days;
        return remaining < 0 ? 0 : remaining;
    }

    /// <summary>
    /// Verifica se l'abbonamento sta per scadere (entro i prossimi N giorni)
    /// </summary>
    public bool IsExpiringSoon(int daysThreshold = 30)
    {
        if (!EndDate.HasValue)
            return false;

        var daysRemaining = GetDaysRemaining();
        return daysRemaining.HasValue && daysRemaining.Value <= daysThreshold && daysRemaining.Value > 0;
    }
}
