using DocumentOperator.Application.Common.Configuration;
using DocumentOperator.Application.Common.DTOs;
using DocumentOperator.Application.Common.Interfaces;
using MediatR;
using Microsoft.Extensions.Options;

namespace DocumentOperator.Application.HasZugferd.Queries;

/// <summary>
/// Query for checking if PDF contains ZUGFeRD XML attachment
/// </summary>
public record HasZugferdQuery : IRequest<ZugferdCheckResult>
{
    /// <summary>
    /// PDF as stream (caller is responsible for disposal)
    /// </summary>
    public required Stream PdfStream { get; init; }
}

/// <summary>
/// Handler for HasZugferdQuery
/// Checks if PDF contains ZUGFeRD/Factur-X XML attachment
/// </summary>
public class HasZugferdQueryHandler(
    IPdfProcessor pdfProcessor,
    IOptions<ZugferdSettings> settings)
    : IRequestHandler<HasZugferdQuery, ZugferdCheckResult>
{
    private readonly ZugferdSettings _settings = settings.Value;

    /// <summary>
    /// Checks if PDF contains ZUGFeRD XML and returns metadata
    /// </summary>
    public async Task<ZugferdCheckResult> Handle(HasZugferdQuery request, CancellationToken cancellationToken)
    {
        // Get all attachments
        var attachmentInfo = await pdfProcessor.CheckAttachmentsAsync(request.PdfStream);

        // Check for ZUGFeRD/Factur-X XML files using configured names and patterns
        var zugferdAttachment = attachmentInfo.Attachments.FirstOrDefault(a =>
            _settings.ZugferdFileNames.Any(name => 
                a.FileName.Equals(name, StringComparison.OrdinalIgnoreCase)) ||
            _settings.ZugferdFileNamePatterns.Any(pattern => 
                a.FileName.Contains(pattern, StringComparison.OrdinalIgnoreCase)));

        if (zugferdAttachment != null)
        {
            return new ZugferdCheckResult
            {
                HasZugferd = true,
                ZugferdFileName = zugferdAttachment.FileName,
                ZugferdFileSize = zugferdAttachment.SizeBytes,
                ZugferdMimeType = zugferdAttachment.MimeType
            };
        }

        return new ZugferdCheckResult
        {
            HasZugferd = false
        };
    }
}
