using MediatR;
using TakeoutSaaS.Application.App.Billings.Commands;
using TakeoutSaaS.Application.App.Billings.Contracts;
using TakeoutSaaS.Domain.Billings.Entities;
using TakeoutSaaS.Domain.Billings.Enums;
using TakeoutSaaS.Domain.Billings.Repositories;
using TakeoutSaaS.Shared.Abstractions.Security;

namespace TakeoutSaaS.Application.App.Billings.Handlers;

/// <summary>
/// 确认收款命令处理器。
/// </summary>
public sealed class ConfirmPaymentCommandHandler(
    IBillingRepository billingRepository,
    ICurrentUserAccessor currentUserAccessor)
    : IRequestHandler<ConfirmPaymentCommand, PaymentRecordDto?>
{
    /// <inheritdoc />
    public async Task<PaymentRecordDto?> Handle(
        ConfirmPaymentCommand request,
        CancellationToken cancellationToken)
    {
        // 1. 获取账单（带跟踪）
        var billing = await billingRepository.GetByIdForUpdateAsync(request.BillingId, cancellationToken);

        // 2. 如果不存在，返回 null
        if (billing is null)
        {
            return null;
        }

        // 3. 获取当前用户 ID
        var currentUserId = currentUserAccessor.UserId;
        var now = DateTime.UtcNow;

        // 4. 创建支付记录（已审核通过状态）
        var payment = new TenantPayment
        {
            TenantId = billing.TenantId,
            BillingStatementId = billing.Id,
            Amount = request.Amount,
            Method = request.Method,
            Status = TenantPaymentStatus.Success,
            TransactionNo = request.TransactionNo,
            ProofUrl = request.ProofUrl,
            Notes = request.Notes,
            PaidAt = now,
            VerifiedBy = currentUserId,
            VerifiedAt = now,
            CreatedAt = now,
            CreatedBy = currentUserId
        };

        // 5. 添加支付记录
        await billingRepository.AddPaymentAsync(payment, cancellationToken);

        // 6. 更新账单已付金额
        billing.AmountPaid += request.Amount;

        // 7. 如果已付金额 >= 应付金额，更新账单状态为已支付
        if (billing.AmountPaid >= billing.AmountDue)
        {
            billing.Status = TenantBillingStatus.Paid;
        }

        // 8. 更新账单时间戳
        billing.UpdatedAt = now;

        // 9. 保存变更
        await billingRepository.SaveChangesAsync(cancellationToken);

        // 10. 返回支付记录 DTO
        return new PaymentRecordDto
        {
            Id = payment.Id,
            BillingStatementId = payment.BillingStatementId,
            Amount = payment.Amount,
            Method = (int)payment.Method,
            Status = (int)payment.Status,
            TransactionNo = payment.TransactionNo,
            ProofUrl = payment.ProofUrl,
            PaidAt = payment.PaidAt,
            Notes = payment.Notes,
            VerifiedBy = payment.VerifiedBy,
            VerifiedAt = payment.VerifiedAt,
            RefundReason = payment.RefundReason,
            RefundedAt = payment.RefundedAt,
            CreatedAt = payment.CreatedAt
        };
    }
}
