using DevExpress.Pdf;
using DXApp.TemplateKitProject.Models;

namespace DXApp.TemplateKitProject.Services;

public class PdfResultPackageService(
    IConfiguration configuration,
    ILogger<PdfResultPackageService> logger)
{
    public async Task<string?> CreateResultPackageAsync(
        byte[] originalPdfBytes,
        string originalFileName,
        ZugferdInvoice invoice)
    {
        // 1. Bericht-PDF suchen
        var reportPath = FindReportFile(originalFileName);
        if (reportPath is null)
        {
            logger.LogWarning(
                "Kein Ergebnisbericht gefunden für '{FileName}'.", originalFileName);
            return null;
        }

        logger.LogInformation(
            "Ergebnisbericht gefunden: '{ReportPath}'.", reportPath);

        // 2. Ausgabepfad bestimmen
        var outputDir = configuration["PdfResults:OutputDirectory"]
            ?? Path.Combine(Path.GetTempPath(), "PdfResults");
        Directory.CreateDirectory(outputDir);

        var baseName = Path.GetFileNameWithoutExtension(originalFileName);
        var outputPath = Path.Combine(outputDir, $"{baseName}_result.pdf");

        // 3. Original auf PDF/A-3b hochstufen + Bericht anhängen
        await Task.Run(() =>
        {
            // Original in MemoryStream laden
            using var inputStream = new MemoryStream(originalPdfBytes);
            using var outputStream = new MemoryStream();

            // PDF/A-3b Konvertierung
            var converter = new PdfDocumentConverter(inputStream);
            converter.Convert(PdfCompatibility.PdfA3b);

            // Konvertiertes PDF in MemoryStream speichern
            using var convertedStream = new MemoryStream();
            converter.SaveDocument(convertedStream);
            convertedStream.Position = 0;

            // Bericht als Anhang einbetten
            using var processor = new PdfDocumentProcessor();
            processor.LoadDocument(convertedStream);

            processor.AttachFile(new PdfFileAttachment
            {
                FileName = Path.GetFileName(reportPath),
                Description = "Ergebnisbericht",
                MimeType = "application/pdf",
                Relationship = PdfAssociatedFileRelationship.Supplement,
                CreationDate = DateTime.Now,
                Data = File.ReadAllBytes(reportPath)
            });

            // Speichern
            processor.SaveDocument(outputPath);
        });

        logger.LogInformation(
            "Result-PDF gespeichert: '{OutputPath}'.", outputPath);

        return outputPath;
    }

    private string? FindReportFile(string originalFileName)
    {
        var inputDir = configuration["PdfResultReports:InputDirectory"]
            ?? Path.Combine(Path.GetTempPath(), "PdfResultReports");

        if (!Directory.Exists(inputDir))
        {
            logger.LogWarning("Berichtsverzeichnis nicht gefunden: '{Dir}'.", inputDir);
            return null;
        }

        // Konvention Option A: {originalname}_report.pdf
        var baseName = Path.GetFileNameWithoutExtension(originalFileName);
        var reportName = $"{baseName}_report.pdf";
        var reportPath = Path.Combine(inputDir, reportName);

        return File.Exists(reportPath) ? reportPath : null;
    }
}