using System.Text.Json.Serialization;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Shared.Abstractions.Serialization;

namespace TakeoutSaaS.Application.App.Billings.Dto.Legacy;

/// <summary>
/// 账单列表 DTO（用于列表展示）。
/// </summary>
public sealed record BillingListDto
{
    /// <summary>
    /// 账单 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long Id { get; init; }

    /// <summary>
    /// 租户 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long TenantId { get; init; }

    /// <summary>
    /// 租户名称。
    /// </summary>
    public string TenantName { get; init; } = string.Empty;

    /// <summary>
    /// 关联订阅 ID（仅订阅/续费账单可能有值）。
    /// </summary>
    [JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
    public long? SubscriptionId { get; init; }

    /// <summary>
    /// 账单编号。
    /// </summary>
    public string StatementNo { get; init; } = string.Empty;

    /// <summary>
    /// 账单类型。
    /// </summary>
    public BillingType BillingType { get; init; }

    /// <summary>
    /// 计费周期开始时间（UTC）。
    /// </summary>
    public DateTime PeriodStart { get; init; }

    /// <summary>
    /// 计费周期结束时间（UTC）。
    /// </summary>
    public DateTime PeriodEnd { get; init; }

    /// <summary>
    /// 应付金额。
    /// </summary>
    public decimal AmountDue { get; init; }

    /// <summary>
    /// 折扣金额。
    /// </summary>
    public decimal DiscountAmount { get; init; }

    /// <summary>
    /// 税费金额。
    /// </summary>
    public decimal TaxAmount { get; init; }

    /// <summary>
    /// 总金额（应付金额 - 折扣 + 税费）。
    /// </summary>
    public decimal TotalAmount { get; init; }

    /// <summary>
    /// 已付金额。
    /// </summary>
    public decimal AmountPaid { get; init; }

    /// <summary>
    /// 币种。
    /// </summary>
    public string Currency { get; init; } = "CNY";

    /// <summary>
    /// 账单状态。
    /// </summary>
    public TenantBillingStatus Status { get; init; }

    /// <summary>
    /// 到期日（UTC）。
    /// </summary>
    public DateTime DueDate { get; init; }

    /// <summary>
    /// 是否已逾期（根据到期日与状态综合判断）。
    /// </summary>
    public bool IsOverdue { get; init; }

    /// <summary>
    /// 逾期天数（未逾期为 0）。
    /// </summary>
    public int OverdueDays { get; init; }

    /// <summary>
    /// 创建时间（UTC）。
    /// </summary>
    public DateTime CreatedAt { get; init; }

    /// <summary>
    /// 更新时间（UTC）。
    /// </summary>
    public DateTime? UpdatedAt { get; init; }
}

/// <summary>
/// 账单详情 DTO（含明细项）。
/// </summary>
public sealed record BillingDetailDto
{
    /// <summary>
    /// 账单 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long Id { get; init; }

    /// <summary>
    /// 租户 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long TenantId { get; init; }

    /// <summary>
    /// 租户名称。
    /// </summary>
    public string TenantName { get; init; } = string.Empty;

    /// <summary>
    /// 账单编号。
    /// </summary>
    public string StatementNo { get; init; } = string.Empty;

    /// <summary>
    /// 关联订阅 ID（仅订阅/续费账单可能有值）。
    /// </summary>
    [JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
    public long? SubscriptionId { get; init; }

    /// <summary>
    /// 账单类型。
    /// </summary>
    public BillingType BillingType { get; init; }

    /// <summary>
    /// 计费周期开始时间（UTC）。
    /// </summary>
    public DateTime PeriodStart { get; init; }

    /// <summary>
    /// 计费周期结束时间（UTC）。
    /// </summary>
    public DateTime PeriodEnd { get; init; }

    /// <summary>
    /// 应付金额。
    /// </summary>
    public decimal AmountDue { get; init; }

    /// <summary>
    /// 折扣金额。
    /// </summary>
    public decimal DiscountAmount { get; init; }

    /// <summary>
    /// 税费金额。
    /// </summary>
    public decimal TaxAmount { get; init; }

    /// <summary>
    /// 总金额（应付金额 - 折扣 + 税费）。
    /// </summary>
    public decimal TotalAmount { get; init; }

    /// <summary>
    /// 已付金额。
    /// </summary>
    public decimal AmountPaid { get; init; }

    /// <summary>
    /// 币种。
    /// </summary>
    public string Currency { get; init; } = "CNY";

    /// <summary>
    /// 账单状态。
    /// </summary>
    public TenantBillingStatus Status { get; init; }

    /// <summary>
    /// 到期日（UTC）。
    /// </summary>
    public DateTime DueDate { get; init; }

    /// <summary>
    /// 账单明细 JSON。
    /// </summary>
    public string? LineItemsJson { get; init; }

    /// <summary>
    /// 账单明细列表（从 JSON 反序列化）。
    /// </summary>
    public IReadOnlyList<BillingLineItemDto> LineItems { get; init; } = [];

    /// <summary>
    /// 支付记录列表。
    /// </summary>
    public IReadOnlyList<PaymentRecordDto> Payments { get; init; } = [];

    /// <summary>
    /// 备注信息。
    /// </summary>
    public string? Notes { get; init; }

    /// <summary>
    /// 创建时间（UTC）。
    /// </summary>
    public DateTime CreatedAt { get; init; }

    /// <summary>
    /// 更新时间（UTC）。
    /// </summary>
    public DateTime? UpdatedAt { get; init; }
}

/// <summary>
/// 账单明细项 DTO。
/// </summary>
public sealed record BillingLineItemDto
{
    /// <summary>
    /// 明细类型（如：套餐费、配额包费用、其他费用）。
    /// </summary>
    public string ItemType { get; init; } = string.Empty;

    /// <summary>
    /// 描述。
    /// </summary>
    public string Description { get; init; } = string.Empty;

    /// <summary>
    /// 数量。
    /// </summary>
    public decimal Quantity { get; init; }

    /// <summary>
    /// 单价。
    /// </summary>
    public decimal UnitPrice { get; init; }

    /// <summary>
    /// 金额（数量 × 单价）。
    /// </summary>
    public decimal Amount { get; init; }

    /// <summary>
    /// 折扣率（0-1）。
    /// </summary>
    public decimal? DiscountRate { get; init; }
}

/// <summary>
/// 支付记录 DTO。
/// </summary>
public sealed record PaymentRecordDto
{
    /// <summary>
    /// 支付记录 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long Id { get; init; }

    /// <summary>
    /// 租户 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long TenantId { get; init; }

    /// <summary>
    /// 账单 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long BillingId { get; init; }

    /// <summary>
    /// 支付金额。
    /// </summary>
    public decimal Amount { get; init; }

    /// <summary>
    /// 支付方式。
    /// </summary>
    public TenantPaymentMethod Method { get; init; }

    /// <summary>
    /// 支付状态。
    /// </summary>
    public TenantPaymentStatus Status { get; init; }

    /// <summary>
    /// 支付流水号。
    /// </summary>
    public string? TransactionNo { get; init; }

    /// <summary>
    /// 支付凭证 URL。
    /// </summary>
    public string? ProofUrl { get; init; }

    /// <summary>
    /// 备注。
    /// </summary>
    public string? Notes { get; init; }

    /// <summary>
    /// 审核状态（待审核/已通过/已拒绝）。
    /// </summary>
    public bool IsVerified { get; init; }

    /// <summary>
    /// 审核人 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
    public long? VerifiedBy { get; init; }

    /// <summary>
    /// 审核时间（UTC）。
    /// </summary>
    public DateTime? VerifiedAt { get; init; }

    /// <summary>
    /// 退款原因。
    /// </summary>
    public string? RefundReason { get; init; }

    /// <summary>
    /// 退款时间（UTC）。
    /// </summary>
    public DateTime? RefundedAt { get; init; }

    /// <summary>
    /// 支付时间（UTC）。
    /// </summary>
    public DateTime? PaidAt { get; init; }

    /// <summary>
    /// 创建时间（UTC）。
    /// </summary>
    public DateTime CreatedAt { get; init; }
}

/// <summary>
/// 账单统计 DTO。
/// </summary>
public sealed record BillingStatisticsDto
{
    /// <summary>
    /// 租户 ID（当前租户）。
    /// </summary>
    [JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
    public long? TenantId { get; init; }

    /// <summary>
    /// 统计周期开始时间（UTC）。
    /// </summary>
    public DateTime StartDate { get; init; }

    /// <summary>
    /// 统计周期结束时间（UTC）。
    /// </summary>
    public DateTime EndDate { get; init; }

    /// <summary>
    /// 分组方式（Day/Week/Month）。
    /// </summary>
    public string GroupBy { get; init; } = "Day";

    /// <summary>
    /// 总账单数量。
    /// </summary>
    public int TotalCount { get; init; }

    /// <summary>
    /// 待付款账单数量。
    /// </summary>
    public int PendingCount { get; init; }

    /// <summary>
    /// 已付款账单数量。
    /// </summary>
    public int PaidCount { get; init; }

    /// <summary>
    /// 逾期账单数量。
    /// </summary>
    public int OverdueCount { get; init; }

    /// <summary>
    /// 已取消账单数量。
    /// </summary>
    public int CancelledCount { get; init; }

    /// <summary>
    /// 总应收金额（账单原始应付）。
    /// </summary>
    public decimal TotalAmountDue { get; init; }

    /// <summary>
    /// 总实收金额。
    /// </summary>
    public decimal TotalAmountPaid { get; init; }

    /// <summary>
    /// 总未收金额（总金额 - 实收）。
    /// </summary>
    public decimal TotalAmountUnpaid { get; init; }

    /// <summary>
    /// 逾期未收金额。
    /// </summary>
    public decimal TotalOverdueAmount { get; init; }

    /// <summary>
    /// 分组统计：应收金额趋势（Key 为分组起始日期 yyyy-MM-dd）。
    /// </summary>
    public Dictionary<string, decimal> AmountDueTrend { get; init; } = [];

    /// <summary>
    /// 分组统计：实收金额趋势（Key 为分组起始日期 yyyy-MM-dd）。
    /// </summary>
    public Dictionary<string, decimal> AmountPaidTrend { get; init; } = [];

    /// <summary>
    /// 分组统计：账单数量趋势（Key 为分组起始日期 yyyy-MM-dd）。
    /// </summary>
    public Dictionary<string, int> CountTrend { get; init; } = [];
}

/// <summary>
/// 账单导出 DTO。
/// </summary>
public sealed record BillingExportDto
{
    /// <summary>
    /// 账单 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long Id { get; init; }

    /// <summary>
    /// 租户 ID（雪花算法，序列化为字符串）。
    /// </summary>
    [JsonConverter(typeof(SnowflakeIdJsonConverter))]
    public long TenantId { get; init; }

    /// <summary>
    /// 租户名称。
    /// </summary>
    public string TenantName { get; init; } = string.Empty;

    /// <summary>
    /// 账单编号。
    /// </summary>
    public string StatementNo { get; init; } = string.Empty;

    /// <summary>
    /// 关联订阅 ID（仅订阅/续费账单可能有值）。
    /// </summary>
    [JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
    public long? SubscriptionId { get; init; }

    /// <summary>
    /// 账单类型。
    /// </summary>
    public BillingType BillingType { get; init; }

    /// <summary>
    /// 计费周期开始时间（UTC）。
    /// </summary>
    public DateTime PeriodStart { get; init; }

    /// <summary>
    /// 计费周期结束时间（UTC）。
    /// </summary>
    public DateTime PeriodEnd { get; init; }

    /// <summary>
    /// 应付金额。
    /// </summary>
    public decimal AmountDue { get; init; }

    /// <summary>
    /// 折扣金额。
    /// </summary>
    public decimal DiscountAmount { get; init; }

    /// <summary>
    /// 税费金额。
    /// </summary>
    public decimal TaxAmount { get; init; }

    /// <summary>
    /// 总金额。
    /// </summary>
    public decimal TotalAmount { get; init; }

    /// <summary>
    /// 已付金额。
    /// </summary>
    public decimal AmountPaid { get; init; }

    /// <summary>
    /// 账单状态。
    /// </summary>
    public TenantBillingStatus Status { get; init; }

    /// <summary>
    /// 币种。
    /// </summary>
    public string Currency { get; init; } = "CNY";

    /// <summary>
    /// 到期日（UTC）。
    /// </summary>
    public DateTime DueDate { get; init; }

    /// <summary>
    /// 备注信息。
    /// </summary>
    public string? Notes { get; init; }

    /// <summary>
    /// 账单明细列表。
    /// </summary>
    public List<BillingLineItemDto> LineItems { get; init; } = [];
}
