using Microsoft.EntityFrameworkCore;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Domain.Tenants.Repositories;
using TakeoutSaaS.Infrastructure.App.Persistence;

namespace TakeoutSaaS.Infrastructure.App.Persistence.Repositories;

/// <summary>
/// 租户支付记录仓储实现（EF Core）。
/// </summary>
public sealed class TenantPaymentRepository(TakeoutAppDbContext context) : ITenantPaymentRepository
{
    /// <inheritdoc />
    public async Task<IReadOnlyList<TenantPayment>> GetByBillingIdAsync(long billingStatementId, CancellationToken cancellationToken = default)
    {
        return await context.TenantPayments
            .IgnoreQueryFilters()
            .AsNoTracking()
            .Where(x => x.DeletedAt == null && x.BillingStatementId == billingStatementId)
            .OrderByDescending(x => x.CreatedAt)
            .ToListAsync(cancellationToken);
    }

    /// <inheritdoc />
    public async Task<decimal> GetTotalPaidAmountAsync(long billingStatementId, CancellationToken cancellationToken = default)
    {
        // 1. 仅统计支付成功的记录
        return await context.TenantPayments
            .IgnoreQueryFilters()
            .AsNoTracking()
            .Where(x => x.DeletedAt == null
                        && x.BillingStatementId == billingStatementId
                        && x.Status == TenantPaymentStatus.Success)
            .SumAsync(x => x.Amount, cancellationToken);
    }

    /// <inheritdoc />
    public Task<TenantPayment?> FindByIdAsync(long paymentId, CancellationToken cancellationToken = default)
    {
        return context.TenantPayments
            .IgnoreQueryFilters()
            .AsNoTracking()
            .FirstOrDefaultAsync(x => x.DeletedAt == null && x.Id == paymentId, cancellationToken);
    }

    /// <inheritdoc />
    public Task<TenantPayment?> GetByTransactionNoAsync(string transactionNo, CancellationToken cancellationToken = default)
    {
        var normalized = transactionNo.Trim();

        return context.TenantPayments
            .IgnoreQueryFilters()
            .AsNoTracking()
            .FirstOrDefaultAsync(x => x.DeletedAt == null && x.TransactionNo == normalized, cancellationToken);
    }

    /// <inheritdoc />
    public Task AddAsync(TenantPayment payment, CancellationToken cancellationToken = default)
    {
        return context.TenantPayments.AddAsync(payment, cancellationToken).AsTask();
    }

    /// <inheritdoc />
    public Task UpdateAsync(TenantPayment payment, CancellationToken cancellationToken = default)
    {
        context.TenantPayments.Update(payment);
        return Task.CompletedTask;
    }

    /// <inheritdoc />
    public Task SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        return context.SaveChangesAsync(cancellationToken);
    }
}
