using System.Text.Json;
using MediatR;
using TakeoutSaaS.Application.App.Billings.Contracts;
using TakeoutSaaS.Application.App.Billings.Queries;
using TakeoutSaaS.Domain.Billings.Repositories;

namespace TakeoutSaaS.Application.App.Billings.Handlers;

/// <summary>
/// 获取账单详情查询处理器。
/// </summary>
public sealed class GetBillingDetailQueryHandler(IBillingRepository billingRepository)
    : IRequestHandler<GetBillingDetailQuery, BillingDetailDto?>
{
    /// <inheritdoc />
    public async Task<BillingDetailDto?> Handle(
        GetBillingDetailQuery request,
        CancellationToken cancellationToken)
    {
        // 1. 查询账单详情
        var detail = await billingRepository.GetDetailAsync(request.BillingId, cancellationToken);

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

        // 3. 查询支付记录
        var payments = await billingRepository.GetPaymentsByBillingIdAsync(request.BillingId, cancellationToken);

        // 4. 映射支付记录为 DTO
        var paymentDtos = payments.Select(p => new PaymentRecordDto
        {
            Id = p.Id,
            BillingStatementId = p.BillingStatementId,
            Amount = p.Amount,
            Method = (int)p.Method,
            Status = (int)p.Status,
            TransactionNo = p.TransactionNo,
            ProofUrl = p.ProofUrl,
            PaidAt = p.PaidAt,
            Notes = p.Notes,
            VerifiedBy = p.VerifiedBy,
            VerifiedAt = p.VerifiedAt,
            RefundReason = p.RefundReason,
            RefundedAt = p.RefundedAt,
            CreatedAt = p.CreatedAt
        }).ToList();

        // 5. 解析账单明细 JSON
        List<BillingLineItemDto>? lineItems = null;
        if (!string.IsNullOrEmpty(detail.LineItemsJson))
        {
            try
            {
                lineItems = JsonSerializer.Deserialize<List<BillingLineItemDto>>(detail.LineItemsJson);
            }
            catch
            {
                // 解析失败时忽略
            }
        }

        // 6. 映射为 DTO 并返回
        return new BillingDetailDto
        {
            Id = detail.Id,
            TenantId = detail.TenantId,
            TenantName = detail.TenantName,
            StatementNo = detail.StatementNo,
            BillingType = detail.BillingType,
            PeriodStart = detail.PeriodStart,
            PeriodEnd = detail.PeriodEnd,
            AmountDue = detail.AmountDue,
            AmountPaid = detail.AmountPaid,
            DiscountAmount = detail.DiscountAmount,
            TaxAmount = detail.TaxAmount,
            Currency = detail.Currency,
            Status = detail.Status,
            DueDate = detail.DueDate,
            LineItemsJson = detail.LineItemsJson,
            LineItems = lineItems,
            Notes = detail.Notes,
            OverdueNotifiedAt = detail.OverdueNotifiedAt,
            ReminderSentAt = detail.ReminderSentAt,
            CreatedAt = detail.CreatedAt,
            UpdatedAt = detail.UpdatedAt,
            Payments = paymentDtos
        };
    }
}
