using DXApp.TemplateKitProject.Data;
using DXApp.TemplateKitProject.Models;
using DXApp.TemplateKitProject.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace DXApp.TemplateKitProject.Pages.Invoices;

public class UploadModel(
    PdfAttachmentExtractorService extractor,
    ZugferdImportService zugferdImportService,
    PdfResultPackageService resultPackageService,
    AppDbContext db,
    ILogger<UploadModel> logger) : PageModel
{
    [BindProperty]
    public IFormFile? PdfFile { get; set; }

    public PdfExtractionResult? Result { get; private set; }
    public bool ExtractionDone { get; private set; }
    public string? ErrorMessage { get; private set; }
    public ZugferdInvoice? ImportedInvoice { get; private set; }
    public string? ResultFilePath { get; private set; }
    public bool IsDuplicate { get; private set; }

    public void OnGet()
    { }

    public async Task<IActionResult> OnPostAsync()
    {
        if (PdfFile is null || PdfFile.Length == 0)
        {
            ModelState.AddModelError(nameof(PdfFile), "Bitte eine PDF-Datei auswählen.");
            return Page();
        }

        if (!PdfFile.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
        {
            ModelState.AddModelError(nameof(PdfFile), "Nur PDF-Dateien sind erlaubt.");
            return Page();
        }

        ExtractionDone = true;

        try
        {
            // Stream in MemoryStream puffern → kann zweimal gelesen werden
            using var memStream = new MemoryStream();
            await PdfFile.CopyToAsync(memStream);
            var originalBytes = memStream.ToArray();  // ← neu: als byte[] merken

            // 1. Anhänge extrahieren
            memStream.Position = 0;
            Result = extractor.ExtractAttachments(memStream, PdfFile.FileName);

            // 2. Wenn ZUGFeRD-XML gefunden → parsen und in DB speichern
            if (Result.HasZugferdXml)
            {
                memStream.Position = 0;
                ImportedInvoice = await zugferdImportService.ImportAsync(memStream, "Upload", Result.ZugferdGuidelineId);

                // Duplikat erkennen: vorhandener Eintrag hat ImportedAt von früher
                if (ImportedInvoice is not null && ImportedInvoice.ImportedAt < DateTime.UtcNow.AddSeconds(-5))
                    IsDuplicate = true;

                // 3. Result-Package erstellen (nur wenn Import erfolgreich UND kein Duplikat)
                if (ImportedInvoice is not null && !IsDuplicate)
                {
                    ResultFilePath = await resultPackageService.CreateResultPackageAsync(
                        originalBytes, PdfFile.FileName, ImportedInvoice);

                    // ResultFilePath in DB aktualisieren
                    if (ResultFilePath is not null)
                    {
                        ImportedInvoice.ResultFilePath = ResultFilePath;
                        await db.SaveChangesAsync();
                    }

                    // 4. Attachments in DB speichern
                    if (Result.HasAttachments)
                    {
                        foreach (var attachment in Result.Attachments)
                        {
                            var invoiceAttachment = new InvoiceAttachment
                            {
                                ZugferdInvoiceId = ImportedInvoice.Id,
                                OriginalFileName = attachment.OriginalFileName,
                                SavedFilePath = attachment.SavedFilePath,
                                FileSizeBytes = attachment.FileSizeBytes,
                                IsZugferdXml = attachment.IsZugferdXml,
                                ExtractedAt = DateTime.UtcNow
                            };
                            db.InvoiceAttachments.Add(invoiceAttachment);
                        }
                        await db.SaveChangesAsync();

                        logger.LogInformation(
                            "Rechnung '{InvoiceNumber}': {Count} Anhang/Anhänge in DB gespeichert.",
                            ImportedInvoice.InvoiceNumber, Result.Attachments.Count);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Fehler beim Verarbeiten der Datei '{FileName}'.", PdfFile.FileName);
            ErrorMessage = $"Fehler beim Verarbeiten der Datei: {ex.Message}";
        }

        return Page();
    }
}