using System.Globalization;
using System.Text;
using MediatR;
using TakeoutSaaS.Application.App.Finance.Transactions.Dto;
using TakeoutSaaS.Application.App.Finance.Transactions.Queries;
using TakeoutSaaS.Domain.Finance.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Finance.Transactions.Handlers;

/// <summary>
/// 交易流水 CSV 导出查询处理器。
/// </summary>
public sealed class ExportFinanceTransactionCsvQueryHandler(
    IFinanceTransactionRepository financeTransactionRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<ExportFinanceTransactionCsvQuery, FinanceTransactionExportDto>
{
    /// <inheritdoc />
    public async Task<FinanceTransactionExportDto> Handle(ExportFinanceTransactionCsvQuery request, CancellationToken cancellationToken)
    {
        // 1. 按筛选读取导出数据。
        var tenantId = tenantProvider.GetCurrentTenantId();
        var records = await financeTransactionRepository.ListForExportAsync(
            tenantId,
            request.StoreId,
            request.StartAt,
            request.EndAt,
            request.TransactionType,
            request.DeliveryType,
            request.PaymentMethod,
            request.Keyword,
            cancellationToken);

        // 2. 组装 CSV 并输出 Base64。
        var csv = BuildCsv(records.Select(FinanceTransactionMapping.ToListItem).ToList());
        var bytes = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(csv)).ToArray();

        return new FinanceTransactionExportDto
        {
            FileName = $"交易流水_{DateTime.UtcNow:yyyyMMddHHmmss}.csv",
            FileContentBase64 = Convert.ToBase64String(bytes),
            TotalCount = records.Count
        };
    }

    private static string BuildCsv(IReadOnlyList<FinanceTransactionListItemDto> rows)
    {
        var builder = new StringBuilder();
        builder.AppendLine("流水号,关联订单,类型,渠道,支付方式,金额,交易时间,备注");

        foreach (var row in rows)
        {
            var cells = new[]
            {
                Escape(row.TransactionNo),
                Escape(string.IsNullOrWhiteSpace(row.OrderNo) ? "—" : row.OrderNo!),
                Escape(row.TransactionTypeText),
                Escape(row.ChannelText),
                Escape(row.PaymentMethodText),
                Escape(FinanceTransactionMapping.FormatAmount(row.AmountSigned)),
                Escape(row.OccurredAt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)),
                Escape(string.IsNullOrWhiteSpace(row.Remark) ? "—" : row.Remark)
            };

            builder.AppendLine(string.Join(',', cells));
        }

        return builder.ToString();
    }

    private static string Escape(string value)
    {
        if (!value.Contains('"') && !value.Contains(',') && !value.Contains('\n') && !value.Contains('\r'))
        {
            return value;
        }

        return $"\"{value.Replace("\"", "\"\"")}\"";
    }
}
