namespace PlotLine.Models;

public sealed class SubscriptionLevel
{
    public int SubscriptionLevelID { get; set; }
    public string Name { get; set; } = string.Empty;
    public string DisplayName { get; set; } = string.Empty;
    public string? Description { get; set; }
    public int MaxBooks { get; set; }
    public int MaxChaptersPerBook { get; set; }
    public int MaxScenesPerBook { get; set; }
    public int MaxCharactersPerProject { get; set; }
    public int MaxStorageMB { get; set; }
    public int MaxCollaborators { get; set; }
    public bool IsActive { get; set; }
    public int SortOrder { get; set; }
    public DateTime CreatedDateUTC { get; set; }
    public DateTime ModifiedDateUTC { get; set; }
    public string? StripeMonthlyPriceId { get; set; }
    public string? StripeAnnualPriceId { get; set; }
    public bool RequiresStripeSubscription { get; set; }
    public string? BillingInterval { get; set; }
    public int? MonthlyPricePence { get; set; }
    public int? AnnualPricePence { get; set; }
    public string CurrencyCode { get; set; } = "GBP";
}

public class UserSubscription
{
    public int UserSubscriptionID { get; set; }
    public int UserID { get; set; }
    public int SubscriptionLevelID { get; set; }
    public DateTime StartDateUTC { get; set; }
    public DateTime? EndDateUTC { get; set; }
    public bool IsActive { get; set; }
    public bool IsTrial { get; set; }
    public DateTime? TrialExpiryDateUTC { get; set; }
    public DateTime CreatedDateUTC { get; set; }
    public DateTime ModifiedDateUTC { get; set; }
    public string? StripeCustomerId { get; set; }
    public string? StripeSubscriptionId { get; set; }
    public string? StripePriceId { get; set; }
    public string? BillingInterval { get; set; }
    public string? StripeStatus { get; set; }
    public DateTime? CurrentPeriodStartUTC { get; set; }
    public DateTime? CurrentPeriodEndUTC { get; set; }
    public bool CancelAtPeriodEnd { get; set; }
    public DateTime? CancelledDateUTC { get; set; }
    public DateTime? LastPaymentFailureDateUTC { get; set; }
    public string? LastStripeEventId { get; set; }
}

public sealed class UserSubscriptionDetail : UserSubscription
{
    public string Name { get; set; } = string.Empty;
    public string DisplayName { get; set; } = string.Empty;
    public string? Description { get; set; }
    public int MaxBooks { get; set; }
    public int MaxChaptersPerBook { get; set; }
    public int MaxScenesPerBook { get; set; }
    public int MaxCharactersPerProject { get; set; }
    public int MaxStorageMB { get; set; }
    public int MaxCollaborators { get; set; }
    public bool SubscriptionLevelIsActive { get; set; }
    public int SortOrder { get; set; }
    public int? MonthlyPricePence { get; set; }
    public int? AnnualPricePence { get; set; }
    public string CurrencyCode { get; set; } = "GBP";
    public bool RequiresStripeSubscription { get; set; }
}

public sealed class SubscriptionLimitResult
{
    public bool Allowed { get; init; }
    public int CurrentUsage { get; init; }
    public int MaximumAllowed { get; init; }
    public string Message { get; init; } = string.Empty;

    public static SubscriptionLimitResult AllowedResult(int currentUsage, int maximumAllowed) => new()
    {
        Allowed = true,
        CurrentUsage = currentUsage,
        MaximumAllowed = maximumAllowed
    };

    public static SubscriptionLimitResult Blocked(int currentUsage, int maximumAllowed, string message) => new()
    {
        Allowed = false,
        CurrentUsage = currentUsage,
        MaximumAllowed = maximumAllowed,
        Message = message
    };
}

public sealed class SubscriptionUsageSummary
{
    public int BooksUsed { get; set; }
    public int CollaboratorsUsed { get; set; }
    public int HighestChaptersInBook { get; set; }
    public int HighestScenesInBook { get; set; }
    public int HighestCharactersInProject { get; set; }
    public long StorageUsedBytes { get; set; }
    public long StorageMaximumBytes { get; set; }
}

public sealed class StripeSubscriptionSyncState
{
    public int? UserID { get; set; }
    public int? SubscriptionLevelID { get; set; }
    public string StripeCustomerId { get; set; } = string.Empty;
    public string StripeSubscriptionId { get; set; } = string.Empty;
    public string StripePriceId { get; set; } = string.Empty;
    public string? BillingInterval { get; set; }
    public string StripeStatus { get; set; } = string.Empty;
    public DateTime? CurrentPeriodStartUTC { get; set; }
    public DateTime? CurrentPeriodEndUTC { get; set; }
    public bool CancelAtPeriodEnd { get; set; }
    public string? LastStripeEventId { get; set; }
}

public sealed class StripeCheckoutRequest
{
    public int SubscriptionLevelID { get; set; }
    public string BillingInterval { get; set; } = "Monthly";
}
