using System.Text.Json;
using Tiku.Domain.Common;
using Tiku.Domain.Operations;

namespace Tiku.Domain.Platform;

public sealed class SaasFeature : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string Category { get; set; } = string.Empty;
    public string? Description { get; set; }
    public int ReferencePriceCents { get; set; }
    public string Currency { get; set; } = "CNY";
    public SaasFeatureStatus Status { get; set; } = SaasFeatureStatus.Draft;
    public bool IsCore { get; set; }
    public int SortOrder { get; set; } = 100;
}

public sealed class PermissionModule : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant;
    public string? RequiredFeatureCode { get; set; }
    public string? Description { get; set; }
    public int SortOrder { get; set; } = 100;
}

public sealed class SaasOffering : AuditableEntity
{
    public string Code { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public SaasOfferingType Type { get; set; } = SaasOfferingType.BasePlan;
    public SaasOfferingStatus Status { get; set; } = SaasOfferingStatus.Draft;
    public string? Description { get; set; }
    public int SortOrder { get; set; } = 100;
}

public sealed class SaasOfferingVersion : AuditableEntity
{
    public Guid OfferingId { get; set; }
    public int Version { get; set; } = 1;
    public SaasOfferingVersionStatus Status { get; set; } = SaasOfferingVersionStatus.Draft;
    public PlatformBillingCycle BillingCycle { get; set; } = PlatformBillingCycle.Yearly;
    public int OriginalAmountCents { get; set; }
    public int AmountCents { get; set; }
    public string Currency { get; set; } = "CNY";
    public DateTimeOffset? EffectiveAt { get; set; }
    public DateTimeOffset? PublishedAt { get; set; }
    public DateTimeOffset? RetiredAt { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class SaasOfferingVersionFeature : Entity
{
    public Guid OfferingVersionId { get; set; }
    public string FeatureCode { get; set; } = string.Empty;
}

public sealed class SaasFeatureLimitDefinition : AuditableEntity
{
    public string MetricCode { get; set; } = string.Empty;
    public string FeatureCode { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;
    public string Unit { get; set; } = "count";
    public SaasFeatureLimitKind Kind { get; set; } = SaasFeatureLimitKind.Current;
    public int WarningPercent { get; set; } = 80;
    public bool IsHardLimit { get; set; } = true;
}

public sealed class SaasOfferingVersionLimit : Entity
{
    public Guid OfferingVersionId { get; set; }
    public string MetricCode { get; set; } = string.Empty;
    public long LimitValue { get; set; }
}

public sealed class TenantSaasSubscription : AuditableTenantEntity
{
    public Guid BaseOfferingVersionId { get; set; }
    public Guid? ScheduledBaseOfferingVersionId { get; set; }
    public TenantSaasSubscriptionStatus Status { get; set; } = TenantSaasSubscriptionStatus.Trial;
    public DateTimeOffset StartsAt { get; set; }
    public DateTimeOffset CurrentPeriodStart { get; set; }
    public DateTimeOffset CurrentPeriodEnd { get; set; }
    public bool CancelAtPeriodEnd { get; set; }
    public DateTimeOffset? CancelledAt { get; set; }
    public long LifecycleVersion { get; set; }
    public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}

public sealed class TenantSaasSubscriptionItem : AuditableTenantEntity
{
    public Guid SubscriptionId { get; set; }
    public Guid OfferingVersionId { get; set; }
    public Guid? SourceOrderItemId { get; set; }
    public TenantSaasSubscriptionItemType ItemType { get; set; } = TenantSaasSubscriptionItemType.BasePlan;
    public TenantSaasSubscriptionItemStatus Status { get; set; } = TenantSaasSubscriptionItemStatus.Active;
    public DateTimeOffset StartsAt { get; set; }
    public DateTimeOffset EndsAt { get; set; }
}

public sealed class TenantFeatureOverride : AuditableTenantEntity
{
    public string FeatureCode { get; set; } = string.Empty;
    public TenantFeatureOverrideMode Mode { get; set; } = TenantFeatureOverrideMode.Disabled;
    public DateTimeOffset? ExpiresAt { get; set; }
    public string Reason { get; set; } = string.Empty;
}

public sealed class TenantFeatureUsage : AuditableTenantEntity
{
    public string MetricCode { get; set; } = string.Empty;
    public DateTimeOffset PeriodStart { get; set; }
    public DateTimeOffset PeriodEnd { get; set; }
    public long UsedValue { get; set; }
    public long LimitValueSnapshot { get; set; }
    public bool WarningIssued { get; set; }
    public long Version { get; set; }
}

public sealed class PlatformBillingQuote : AuditableTenantEntity
{
    public string QuoteNo { get; set; } = string.Empty;
    public string IdempotencyKey { get; set; } = string.Empty;
    public PlatformBillingQuoteStatus Status { get; set; } = PlatformBillingQuoteStatus.Active;
    public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription;
    public int OriginalAmountCents { get; set; }
    public int DiscountAmountCents { get; set; }
    public int TotalAmountCents { get; set; }
    public string Currency { get; set; } = "CNY";
    public DateTimeOffset ExpiresAt { get; set; }
    public JsonElement FeatureSnapshot { get; set; } = JsonDefaults.Array();
    public JsonElement LimitSnapshot { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingQuoteItem : Entity, ITenantOwned
{
    public Guid TenantId { get; set; }
    public Guid QuoteId { get; set; }
    public Guid OfferingVersionId { get; set; }
    public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan;
    public int Quantity { get; set; } = 1;
    public int UnitAmountCents { get; set; }
    public int AmountCents { get; set; }
    public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingOrder : AuditableTenantEntity
{
    public Guid QuoteId { get; set; }
    public string OrderNo { get; set; } = string.Empty;
    public string IdempotencyKey { get; set; } = string.Empty;
    public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription;
    public PlatformBillingOrderStatus Status { get; set; } = PlatformBillingOrderStatus.PendingPayment;
    public int OriginalAmountCents { get; set; }
    public int DiscountAmountCents { get; set; }
    public int TotalAmountCents { get; set; }
    public string Currency { get; set; } = "CNY";
    public DateTimeOffset ExpiresAt { get; set; }
    public DateTimeOffset? PaidAt { get; set; }
    public DateTimeOffset? CancelledAt { get; set; }
    public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingOrderItem : Entity, ITenantOwned
{
    public Guid TenantId { get; set; }
    public Guid OrderId { get; set; }
    public Guid OfferingVersionId { get; set; }
    public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan;
    public int Quantity { get; set; } = 1;
    public int UnitAmountCents { get; set; }
    public int AmountCents { get; set; }
    public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingPayment : AuditableTenantEntity
{
    public Guid OrderId { get; set; }
    public string PaymentNo { get; set; } = string.Empty;
    public string IdempotencyKey { get; set; } = string.Empty;
    public string Provider { get; set; } = string.Empty;
    public string Method { get; set; } = string.Empty;
    public PlatformBillingPaymentStatus Status { get; set; } = PlatformBillingPaymentStatus.Pending;
    public int AmountCents { get; set; }
    public string? ProviderTradeNo { get; set; }
    public DateTimeOffset? PaidAt { get; set; }
    public JsonElement ClientPayload { get; set; } = JsonDefaults.Object();
}

public sealed class PlatformBillingPaymentEvent : Entity, ITenantOwned
{
    public Guid TenantId { get; set; }
    public Guid PaymentId { get; set; }
    public string Provider { get; set; } = string.Empty;
    public string ProviderEventId { get; set; } = string.Empty;
    public string EventType { get; set; } = string.Empty;
    public JsonElement Payload { get; set; } = JsonDefaults.Object();
    public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
}

public sealed class PlatformBillingRefund : AuditableTenantEntity
{
    public Guid OrderId { get; set; }
    public Guid? PaymentId { get; set; }
    public string RefundNo { get; set; } = string.Empty;
    public PlatformBillingRefundStatus Status { get; set; } = PlatformBillingRefundStatus.Requested;
    public int AmountCents { get; set; }
    public string Reason { get; set; } = string.Empty;
    public string? ProviderRefundNo { get; set; }
    public DateTimeOffset? CompletedAt { get; set; }
}

public sealed class PlatformBillingInvoice : AuditableTenantEntity
{
    public Guid? OrderId { get; set; }
    public string InvoiceNo { get; set; } = string.Empty;
    public PlatformBillingInvoiceStatus Status { get; set; } = PlatformBillingInvoiceStatus.Draft;
    public int TotalAmountCents { get; set; }
    public string Currency { get; set; } = "CNY";
    public DateOnly? DueDate { get; set; }
    public DateTimeOffset? IssuedAt { get; set; }
    public DateTimeOffset? PaidAt { get; set; }
    public JsonElement BillingProfileSnapshot { get; set; } = JsonDefaults.Object();
}

public enum SaasFeatureStatus { Draft, Active, Archived }
public enum SaasOfferingType { BasePlan, AddOn }
public enum SaasOfferingStatus { Draft, Active, Archived }
public enum SaasOfferingVersionStatus { Draft, Published, Retired }
public enum SaasFeatureLimitKind { Current, Period }
public enum TenantSaasSubscriptionStatus { Trial, Active, PastDue, Cancelled, Expired, Suspended }
public enum TenantSaasSubscriptionItemType { BasePlan, AddOn }
public enum TenantSaasSubscriptionItemStatus { Pending, Active, Scheduled, Cancelled, Expired }
public enum TenantFeatureOverrideMode { Enabled, Disabled }
public enum PlatformBillingQuoteStatus { Active, Converted, Expired, Cancelled }
public enum PlatformBillingOrderPurpose { NewSubscription, Renewal, Upgrade, Downgrade, AddOn }
public enum PlatformBillingOrderStatus { PendingPayment, Paid, Cancelled, Expired, Refunded }
public enum PlatformBillingItemType { BasePlan, AddOn }
public enum PlatformBillingPaymentStatus { Pending, Succeeded, Failed, Refunded }
public enum PlatformBillingRefundStatus { Requested, Processing, Succeeded, Failed, Cancelled }
public enum PlatformBillingInvoiceStatus { Draft, Issued, Paid, Void, Overdue }
