package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.component.UI;
import de.assecutor.votianlt.model.invoices.SystemInvoice;
import de.assecutor.votianlt.model.invoices.SystemInvoiceData;
import de.assecutor.votianlt.model.invoices.SystemInvoiceItem;
import de.assecutor.votianlt.service.SystemInvoiceService;
import jakarta.annotation.security.RolesAllowed;

import java.io.ByteArrayInputStream;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.server.StreamRegistration;

@PageTitle("Rechnungen")
@Route(value = "invoices", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER", "ADMIN" })
public class InvoicesView extends VerticalLayout {

    private final Grid<SystemInvoice> invoiceGrid;

    private final SystemInvoiceService systemInvoiceService;

    public InvoicesView(SystemInvoiceService systemInvoiceService) {
        this.systemInvoiceService = systemInvoiceService;

        setSizeFull();
        setPadding(true);
        setSpacing(true);
        setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
        setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);

        H2 title = new H2("Rechnungen");
        add(title);

        invoiceGrid = new Grid<>(SystemInvoice.class, false);
        invoiceGrid.addColumn(SystemInvoice::getId).setHeader("Rechnungsnummer").setAutoWidth(true);
        invoiceGrid.addColumn(SystemInvoice::getKunde).setHeader("Kunde").setAutoWidth(true);
        invoiceGrid.addColumn(SystemInvoice::getDatum).setHeader("Datum").setAutoWidth(true);
        invoiceGrid.addColumn(SystemInvoice::getBetrag).setHeader("Betrag").setAutoWidth(true);
        invoiceGrid.addColumn(SystemInvoice::getBeschreibung).setHeader("Beschreibung").setAutoWidth(true);
        invoiceGrid.setSelectionMode(Grid.SelectionMode.SINGLE);
        invoiceGrid.getStyle().set("cursor", "pointer");

        // Testdaten
        List<SystemInvoice> testSystemInvoices = List.of(
                new SystemInvoice("R-2024-001", "Max Mustermann", LocalDate.now().minusDays(2), 199.99,
                        "Transport Hamburg-Berlin"),
                new SystemInvoice("R-2024-002", "Erika Musterfrau", LocalDate.now().minusDays(1), 299.49,
                        "Express München-Köln"),
                new SystemInvoice("R-2024-003", "Hans Beispiel", LocalDate.now(), 149.00, "Standard Leipzig-Dresden"));
        invoiceGrid.setItems(testSystemInvoices);

        invoiceGrid.addItemClickListener(event -> {
            SystemInvoice systemInvoice = event.getItem();
            if (systemInvoice != null) {
                downloadInvoicePdf(systemInvoice);
            }
        });

        add(invoiceGrid);
    }

    private void downloadInvoicePdf(SystemInvoice systemInvoice) {
        try {
            // PDF generieren mit SystemInvoice (HTML Template)
            byte[] pdfBytes = generateSystemInvoicePdf(systemInvoice);
            StreamResource resource = new StreamResource(systemInvoice.getId() + ".pdf",
                    () -> new ByteArrayInputStream(pdfBytes));
            resource.setContentType("application/pdf");
            resource.setCacheTime(0);

            // Direkter Download über UI
            StreamRegistration registration = UI.getCurrent().getSession().getResourceRegistry()
                    .registerResource(resource);
            UI.getCurrent().getPage().open(registration.getResourceUri().toString());

        } catch (Exception e) {
            Notification.show("Fehler beim Erstellen der PDF: " + e.getMessage(), 5000, Notification.Position.MIDDLE);
        }
    }

    private byte[] generateSystemInvoicePdf(SystemInvoice systemInvoice) throws Exception {
        DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("dd.MM.yyyy");
        NumberFormat CURRENCY_FMT = NumberFormat.getCurrencyInstance(Locale.GERMANY);

        SystemInvoiceData data = new SystemInvoiceData();
        data.setInvoiceNumber(systemInvoice.getId());
        data.setInvoiceDate(DATE_FMT.format(systemInvoice.getDatum()));
        data.setInvoiceText(systemInvoice.getBeschreibung());

        // Empfänger aus der Zeile (nur Name in den Testdaten vorhanden)
        data.setRecipientName(systemInvoice.getKunde());
        data.setRecipientDepartment("");
        data.setRecipientStreet("");
        data.setRecipientCity("");

        // Eine Position mit dem Betrag/Beschreibung
        List<SystemInvoiceItem> items = new ArrayList<>();
        String netStr = CURRENCY_FMT.format(systemInvoice.getBetrag());
        items.add(new SystemInvoiceItem("1", systemInvoice.getBeschreibung(), netStr, netStr));
        data.setInvoiceItems(items);

        // Summen berechnen (Betrag als Nettobetrag interpretieren)
        double net = systemInvoice.getBetrag();
        double vat = Math.round(net * 0.19 * 100.0) / 100.0;
        double total = net + vat;
        data.setNetAmount(CURRENCY_FMT.format(net));
        data.setVatAmount(CURRENCY_FMT.format(vat));
        data.setTotalAmount(CURRENCY_FMT.format(total));

        return systemInvoiceService.generateInvoicePdfFromHtml(data);
    }
}
