using System.Text;
using MediatR;
using TakeoutSaaS.Application.App.Members.StoredCard.Dto;
using TakeoutSaaS.Application.App.Members.StoredCard.Queries;
using TakeoutSaaS.Domain.Membership.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Members.StoredCard.Handlers;

/// <summary>
/// 导出储值卡充值记录处理器。
/// </summary>
public sealed class ExportStoredCardRechargeRecordCsvQueryHandler(
    IStoredCardRepository repository,
    ITenantProvider tenantProvider)
    : IRequestHandler<ExportStoredCardRechargeRecordCsvQuery, MemberStoredCardRechargeRecordExportDto>
{
    /// <inheritdoc />
    public async Task<MemberStoredCardRechargeRecordExportDto> Handle(
        ExportStoredCardRechargeRecordCsvQuery request,
        CancellationToken cancellationToken)
    {
        var tenantId = tenantProvider.GetCurrentTenantId();
        var normalizedKeyword = MemberStoredCardMapping.NormalizeKeyword(request.Keyword);
        var (startUtc, endUtc) = MemberStoredCardMapping.NormalizeDateRange(request.StartDateUtc, request.EndDateUtc);

        var records = await repository.ListRechargeRecordsForExportAsync(
            tenantId,
            request.StoreId,
            startUtc,
            endUtc,
            normalizedKeyword,
            cancellationToken);

        var csv = BuildCsv(records);
        var bytes = Encoding.UTF8.GetBytes($"\uFEFF{csv}");

        return new MemberStoredCardRechargeRecordExportDto
        {
            FileName = $"储值卡充值记录_{DateTime.UtcNow:yyyyMMddHHmmss}.csv",
            FileContentBase64 = Convert.ToBase64String(bytes),
            TotalCount = records.Count
        };
    }

    private static string BuildCsv(IReadOnlyCollection<Domain.Membership.Entities.MemberStoredCardRechargeRecord> records)
    {
        var lines = new List<string>
        {
            "充值单号,会员,手机号,充值金额,赠送金额,到账金额,支付方式,充值时间"
        };

        foreach (var item in records)
        {
            lines.Add(string.Join(",",
                Escape(item.RecordNo),
                Escape(item.MemberName),
                Escape(item.MemberMobileMasked),
                item.RechargeAmount.ToString("0.00"),
                item.GiftAmount.ToString("0.00"),
                item.ArrivedAmount.ToString("0.00"),
                Escape(MemberStoredCardMapping.ToPaymentMethodDisplayText(item.PaymentMethod)),
                Escape(item.RechargedAt.ToString("yyyy-MM-dd HH:mm:ss"))));
        }

        return string.Join('\n', lines);
    }

    private static string Escape(string value)
    {
        var text = value.Replace("\"", "\"\"");
        return $"\"{text}\"";
    }
}
