using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Tiku.Application.PlatformBilling;
using Tiku.Domain.Platform;

namespace Tiku.Api.Contracts;

/// <summary>
/// 新增或更新SaaS功能请求 DTO。
/// </summary>
public sealed record UpsertSaasFeatureDto(
    Guid? Id,
    [Required, MaxLength(120)] string Code,
    [Required, MaxLength(200)] string Name,
    [Required, MaxLength(100)] string Category,
    [MaxLength(1000)] string? Description,
    [Range(0, int.MaxValue)] int ReferencePriceCents,
    [Required, MaxLength(10)] string Currency,
    SaasFeatureStatus Status,
    int SortOrder)
{
    public UpsertSaasFeatureCommand ToCommand() => new(Id, Code, Name, Category, Description, ReferencePriceCents, Currency, Status, SortOrder);
}

/// <summary>
/// 新增或更新SaaS套餐请求 DTO。
/// </summary>
public sealed record UpsertSaasOfferingDto(
    Guid? Id,
    [Required, MaxLength(120)] string Code,
    [Required, MaxLength(200)] string Name,
    SaasOfferingType Type,
    SaasOfferingStatus Status,
    [MaxLength(1000)] string? Description,
    int SortOrder)
{
    public UpsertSaasOfferingCommand ToCommand() => new(Id, Code, Name, Type, Status, Description, SortOrder);
}

/// <summary>
/// 新增或更新 SaaS 功能额度定义。
/// </summary>
public sealed record UpsertSaasFeatureLimitDto(
    Guid? Id,
    [Required, MaxLength(120)] string MetricCode,
    [Required, MaxLength(120)] string FeatureCode,
    [Required, MaxLength(200)] string Name,
    [Required, MaxLength(50)] string Unit,
    SaasFeatureLimitKind Kind,
    [Range(1, 100)] int WarningPercent,
    bool IsHardLimit)
{
    public UpsertSaasFeatureLimitCommand ToCommand() => new(
        Id, MetricCode, FeatureCode, Name, Unit, Kind, WarningPercent, IsHardLimit);
}

/// <summary>
/// 新增或更新SaaS套餐版本请求 DTO。
/// </summary>
public sealed record UpsertSaasOfferingVersionDto(
    Guid? Id,
    Guid OfferingId,
    PlatformBillingCycle BillingCycle,
    [Range(0, int.MaxValue)] int OriginalAmountCents,
    [Range(0, int.MaxValue)] int AmountCents,
    [Required, MaxLength(10)] string Currency,
    DateTimeOffset? EffectiveAt,
    IReadOnlyCollection<string>? FeatureCodes,
    IReadOnlyDictionary<string, long>? Limits,
    JsonElement Metadata)
{
    public UpsertSaasOfferingVersionCommand ToCommand() => new(
        Id, OfferingId, BillingCycle, OriginalAmountCents, AmountCents, Currency, EffectiveAt,
        FeatureCodes ?? [], Limits ?? new Dictionary<string, long>(), Metadata);
}

/// <summary>
/// 创建平台账务报价请求 DTO。
/// </summary>
public sealed record CreatePlatformBillingQuoteDto(
    Guid BaseOfferingVersionId,
    IReadOnlyCollection<Guid>? AddOnOfferingVersionIds,
    PlatformBillingOrderPurpose Purpose,
    [Required, MaxLength(200)] string IdempotencyKey)
{
    public CreatePlatformBillingQuoteCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? [], Purpose, IdempotencyKey);
}

/// <summary>
/// 创建平台账务订单请求 DTO。
/// </summary>
public sealed record CreatePlatformBillingOrderDto(Guid QuoteId, [Required, MaxLength(200)] string IdempotencyKey)
{
    public CreatePlatformBillingOrderCommand ToCommand() => new(QuoteId, IdempotencyKey);
}

/// <summary>
/// 创建平台账务支付请求 DTO。
/// </summary>
public sealed record CreatePlatformBillingPaymentDto(
    [Required, MaxLength(50)] string Provider,
    [Required, MaxLength(50)] string Method,
    [Required, MaxLength(200)] string IdempotencyKey,
    string? OpenId,
    string? ReturnUrl,
    string? QuitUrl)
{
    public CreatePlatformBillingPaymentCommand ToCommand(string orderNo) =>
        new(orderNo, Provider, Method, IdempotencyKey, OpenId, ReturnUrl, QuitUrl);
}

/// <summary>
/// 变更租户订阅请求 DTO。
/// </summary>
public sealed record ChangeTenantSubscriptionDto(
    Guid BaseOfferingVersionId,
    IReadOnlyCollection<Guid>? AddOnOfferingVersionIds,
    [Required, MaxLength(200)] string IdempotencyKey)
{
    public ChangeTenantSubscriptionCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? []);
}

/// <summary>
/// Idempotent租户账务请求 DTO。
/// </summary>
public sealed record IdempotentTenantBillingDto([Required, MaxLength(200)] string IdempotencyKey);

/// <summary>
/// 确认人工平台支付请求 DTO。
/// </summary>
public sealed record ConfirmManualPlatformPaymentDto(
    Guid PaymentId,
    string? ProviderTradeNo,
    DateTimeOffset? PaidAt,
    [Required, MaxLength(1000)] string Reason)
{
    public ConfirmManualPaymentCommand ToCommand() => new(PaymentId, ProviderTradeNo, PaidAt, Reason);
}

/// <summary>
/// 新增或更新租户功能覆盖规则请求 DTO。
/// </summary>
public sealed record UpsertTenantFeatureOverrideDto(
    Guid TenantId,
    [Required, MaxLength(120)] string FeatureCode,
    TenantFeatureOverrideMode Mode,
    DateTimeOffset? ExpiresAt,
    [Required, MaxLength(1000)] string Reason)
{
    public UpsertTenantFeatureOverrideCommand ToCommand() => new(TenantId, FeatureCode, Mode, ExpiresAt, Reason);
}
