using System.IO.Compression;
using System.Linq;
using System.Text;
using MediatR;
using Microsoft.Extensions.Logging;
using QRCoder;
using TakeoutSaaS.Application.App.Stores.Dto;
using TakeoutSaaS.Application.App.Stores.Queries;
using TakeoutSaaS.Domain.Stores.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Stores.Handlers;

/// <summary>
/// 导出桌码二维码处理器。
/// </summary>
public sealed class ExportStoreTableQRCodesQueryHandler(
    IStoreRepository storeRepository,
    ITenantProvider tenantProvider,
    ILogger<ExportStoreTableQRCodesQueryHandler> logger)
    : IRequestHandler<ExportStoreTableQRCodesQuery, StoreTableExportResult?>
{
    /// <inheritdoc />
    public async Task<StoreTableExportResult?> Handle(ExportStoreTableQRCodesQuery request, CancellationToken cancellationToken)
    {
        // 1. 校验门店存在
        var tenantId = tenantProvider.GetCurrentTenantId();
        var store = await storeRepository.FindByIdAsync(request.StoreId, tenantId, cancellationToken);
        if (store is null)
        {
            return null;
        }

        // 2. 获取桌码列表
        var tables = await storeRepository.GetTablesAsync(request.StoreId, tenantId, cancellationToken);
        if (request.AreaId.HasValue)
        {
            tables = tables.Where(x => x.AreaId == request.AreaId.Value).ToList();
        }

        if (tables.Count == 0)
        {
            return null;
        }

        // 3. 生成 ZIP
        var template = string.IsNullOrWhiteSpace(request.QrContentTemplate) ? "{code}" : request.QrContentTemplate!;
        using var memoryStream = new MemoryStream();
        using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true, Encoding.UTF8))
        {
            foreach (var table in tables)
            {
                var content = BuildPayload(template, table.TableCode);
                var svg = RenderSvg(content);
                var entry = archive.CreateEntry($"{table.TableCode}.svg", CompressionLevel.Fastest);
                using var entryStream = entry.Open();
                using var writer = new StreamWriter(entryStream, Encoding.UTF8);
                writer.Write(svg);
            }
        }

        // 4. 返回导出结果
        var fileName = $"store_{request.StoreId}_tables_{DateTime.UtcNow:yyyyMMddHHmmss}.zip";
        logger.LogInformation("导出门店 {StoreId} 桌码二维码 {Count} 个", request.StoreId, tables.Count);
        return new StoreTableExportResult
        {
            FileName = fileName,
            ContentType = "application/zip",
            Content = memoryStream.ToArray()
        };
    }

    private static string BuildPayload(string template, string tableCode)
    {
        var payload = template.Replace("{code}", tableCode, StringComparison.OrdinalIgnoreCase);
        return string.IsNullOrWhiteSpace(payload) ? tableCode : payload;
    }

    private static string RenderSvg(string payload)
    {
        using var generator = new QRCodeGenerator();
        var data = generator.CreateQrCode(payload, QRCodeGenerator.ECCLevel.Q);
        var svg = new SvgQRCode(data);
        return svg.GetGraphic(5);
    }
}
