using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Shared.Abstractions.Entities;

namespace TakeoutSaaS.Domain.Tenants.Entities;

/// <summary>
/// 租户支付记录。
/// </summary>
public sealed class TenantPayment : MultiTenantEntityBase
{
    /// <summary>
    /// 关联的账单 ID。
    /// </summary>
    public long BillingStatementId { get; set; }

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

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

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

    /// <summary>
    /// 交易号。
    /// </summary>
    public string? TransactionNo { get; set; }

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

    /// <summary>
    /// 支付时间。
    /// </summary>
    public DateTime? PaidAt { get; set; }

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

    /// <summary>
    /// 退款时间。
    /// </summary>
    public DateTime? RefundedAt { get; set; }

    /// <summary>
    /// 审核人 ID（管理员）。
    /// </summary>
    public long? VerifiedBy { get; set; }

    /// <summary>
    /// 审核时间。
    /// </summary>
    public DateTime? VerifiedAt { get; set; }

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

    /// <summary>
    /// 审核支付记录（确认支付有效性）。
    /// </summary>
    public void Verify()
    {
        if (Status != TenantPaymentStatus.Pending)
        {
            throw new InvalidOperationException("只有待审核的支付记录才能被审核。");
        }

        if (VerifiedAt.HasValue)
        {
            throw new InvalidOperationException("该支付记录已经被审核过。");
        }

        // 1. 标记为支付成功
        Status = TenantPaymentStatus.Success;

        // 2. 写入审核时间与支付时间
        VerifiedAt = DateTime.UtcNow;
        PaidAt ??= DateTime.UtcNow;
    }

    /// <summary>
    /// 审核支付记录（确认支付有效性）。
    /// </summary>
    /// <param name="verifierId">审核人 ID。</param>
    public void Verify(long verifierId)
    {
        Verify();
        VerifiedBy = verifierId;
    }

    /// <summary>
    /// 退款。
    /// </summary>
    public void Refund()
    {
        if (string.IsNullOrWhiteSpace(RefundReason))
        {
            throw new InvalidOperationException("退款原因不能为空。");
        }

        Refund(RefundReason);
    }

    /// <summary>
    /// 退款。
    /// </summary>
    /// <param name="reason">退款原因。</param>
    public void Refund(string reason)
    {
        if (Status == TenantPaymentStatus.Refunded)
        {
            throw new InvalidOperationException("该支付记录已经处于退款状态。");
        }

        if (Status != TenantPaymentStatus.Success)
        {
            throw new InvalidOperationException("只有支付成功的记录才能退款。");
        }

        // 1. 标记退款状态
        Status = TenantPaymentStatus.Refunded;

        // 2. 写入退款原因与退款时间
        RefundReason = reason;
        RefundedAt = DateTime.UtcNow;
    }

    /// <summary>
    /// 拒绝支付（审核不通过）。
    /// </summary>
    /// <param name="verifierId">审核人 ID。</param>
    /// <param name="reason">拒绝原因。</param>
    public void Reject(long verifierId, string reason)
    {
        if (Status != TenantPaymentStatus.Pending)
        {
            throw new InvalidOperationException("只有待审核的支付记录才能被拒绝。");
        }

        Status = TenantPaymentStatus.Failed;
        VerifiedBy = verifierId;
        VerifiedAt = DateTime.UtcNow;
        Notes = $"拒绝原因: {reason}";
    }
}
