using System.Globalization;
using MediatR;
using TakeoutSaaS.Application.App.Finance.Reports.Dto;
using TakeoutSaaS.Application.App.Finance.Reports.Queries;
using TakeoutSaaS.Domain.Finance.Repositories;
using TakeoutSaaS.Domain.Finance.Services;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

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

/// <summary>
/// 经营报表 Excel 导出处理器。
/// </summary>
public sealed class ExportFinanceBusinessReportExcelQueryHandler(
    IFinanceBusinessReportRepository financeBusinessReportRepository,
    IFinanceBusinessReportExportService financeBusinessReportExportService,
    ITenantProvider tenantProvider)
    : IRequestHandler<ExportFinanceBusinessReportExcelQuery, FinanceBusinessReportExportDto>
{
    /// <inheritdoc />
    public async Task<FinanceBusinessReportExportDto> Handle(
        ExportFinanceBusinessReportExcelQuery request,
        CancellationToken cancellationToken)
    {
        // 1. 读取租户上下文并确保成本配置存在。
        var tenantId = tenantProvider.GetCurrentTenantId();
        await financeBusinessReportRepository.EnsureDefaultCostProfilesAsync(
            tenantId,
            request.StoreId,
            cancellationToken);

        // 2. 查询报表详情（允许实时补算）。
        var detail = await financeBusinessReportRepository.GetDetailAsync(
            tenantId,
            request.StoreId,
            request.ReportId,
            allowRealtimeBuild: true,
            cancellationToken);

        if (detail is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "经营报表不存在");
        }

        // 3. 导出 Excel 并返回 Base64。
        var fileBytes = await financeBusinessReportExportService.ExportSingleExcelAsync(detail, cancellationToken);
        var periodCode = FinanceBusinessReportMapping.ToPeriodTypeCode(detail.PeriodType);
        return new FinanceBusinessReportExportDto
        {
            FileName = string.Create(
                CultureInfo.InvariantCulture,
                $"business-report-{request.StoreId}-{periodCode}-{request.ReportId}.xlsx"),
            FileContentBase64 = Convert.ToBase64String(fileBytes),
            TotalCount = 1
        };
    }
}
