package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.IFrame;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.textfield.EmailField;
import com.vaadin.flow.component.textfield.TextField;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.tabs.TabSheet;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.validator.EmailValidator;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import de.assecutor.votianlt.model.User;
import de.assecutor.votianlt.model.UserInvoiceData;
import de.assecutor.votianlt.model.invoices.CustomerInvoiceData;
import de.assecutor.votianlt.model.invoices.CustomerInvoiceItem;
import de.assecutor.votianlt.pages.service.UserService;
import de.assecutor.votianlt.pages.service.UserInvoiceDataService;
import de.assecutor.votianlt.security.SecurityService;
import de.assecutor.votianlt.service.CustomerInvoiceService;
import jakarta.annotation.security.RolesAllowed;

@PageTitle("Profil bearbeiten")
@Route(value = "edit-profile", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER", "ADMIN" })
public class EditProfileView extends HorizontalLayout {
    private final TextField prefixField;
    private final TextField ustIdField;
    private final TextField taxNumberField;
    private final TextField bankNameField;
    private final TextField ibanField;
    private final TextField taxRateField;
    private final TextArea introTextArea;
    private final TextArea termsTextArea;
    private final IFrame pdfFrame;

    private final Binder<User> binder = new Binder<>(User.class);
    private final User currentUser;
    private final UserInvoiceDataService userInvoiceDataService;
    private final CustomerInvoiceService customerInvoiceService;
    private UserInvoiceData currentInvoiceData;
    private Checkbox billingEnabled;

    public EditProfileView(UserService userService, UserInvoiceDataService userInvoiceDataService,
                          CustomerInvoiceService customerInvoiceService, SecurityService securityService) {
        this.userInvoiceDataService = userInvoiceDataService;
        this.customerInvoiceService = customerInvoiceService;
        this.currentUser = securityService.getCurrentDatabaseUser();
        setSizeFull();
        setPadding(true);
        setSpacing(true);
        setJustifyContentMode(JustifyContentMode.CENTER);
        // 2% Abstand zwischen den Spalten
        setWidthFull();
        setSpacing(false);
        getStyle().set("column-gap", "2%");

        setAlignItems(Alignment.START);

        // Linke Spalte: Formular
        VerticalLayout formColumn = new VerticalLayout();
        formColumn.setWidth("68%");
        formColumn.setHeightFull();
        formColumn.setPadding(false);
        formColumn.setSpacing(false);
        // TabSheet
        TabSheet tabSheet = new TabSheet();
        tabSheet.setSizeFull();
        formColumn.setFlexGrow(1, tabSheet);

        FormLayout form = new FormLayout();
        form.setWidthFull();
        form.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 2));

        // Firmenfelder
        TextField companyField = new TextField("Firma");
        companyField.addBlurListener(e -> validateField(companyField, "Firma ist ein Pflichtfeld"));

        TextField companyAddField = new TextField("Firmenzusatz");

        TextField firstnameField = new TextField("Vorname");
        firstnameField.addBlurListener(e -> validateField(firstnameField, "Vorname ist ein Pflichtfeld"));

        TextField lastnameField = new TextField("Nachname");
        lastnameField.addBlurListener(e -> validateField(lastnameField, "Nachname ist ein Pflichtfeld"));

        TextField phoneField = new TextField("Telefonnummer");
        phoneField.addBlurListener(e -> validateField(phoneField, "Telefonnummer ist ein Pflichtfeld"));

        TextField faxField = new TextField("Telefon (Fax)");
        TextField mobileField = new TextField("Telefon (Mobil)");

        EmailField emailField = new EmailField("E-Mail-Adresse (Login)*");
        emailField.addBlurListener(e -> validateEmailField(emailField));

        TextField streetField = new TextField("Straße");
        streetField.addBlurListener(e -> validateField(streetField, "Straße ist ein Pflichtfeld"));

        TextField houseNumberField = new TextField("Hausnr");
        houseNumberField.addBlurListener(e -> validateField(houseNumberField, "Hausnummer ist ein Pflichtfeld"));

        TextField addressAddField = new TextField("Adresszusatz");

        TextField zipField = new TextField("Postleitzahl");
        zipField.addBlurListener(e -> validateField(zipField, "Postleitzahl ist ein Pflichtfeld"));

        TextField cityField = new TextField("Stadt");
        cityField.addBlurListener(e -> validateField(cityField, "Stadt ist ein Pflichtfeld"));

        // Abweichende Rechnungsadresse
        Checkbox diffInvoiceAddress = new Checkbox("Abweichende Rechnungsadresse");
        diffInvoiceAddress.getStyle().set("marginTop", "1em");
        // Rechnungsadresse Felder (disabled by default)
        TextField invCompanyField = new TextField("Firma");
        TextField invCompanyAddField = new TextField("Firmenzusatz");
        TextField invFirstnameField = new TextField("Vorname");
        TextField invLastnameField = new TextField("Nachname");
        TextField invStreetField = new TextField("Straße");
        TextField invHouseNumberField = new TextField("Hausnr");
        TextField invAddressAddField = new TextField("Adresszusatz");
        TextField invZipField = new TextField("Postleitzahl");
        TextField invCityField = new TextField("Stadt");
        invCompanyField.setEnabled(false);
        invCompanyAddField.setEnabled(false);
        invFirstnameField.setEnabled(false);
        invLastnameField.setEnabled(false);
        invStreetField.setEnabled(false);
        invHouseNumberField.setEnabled(false);
        invAddressAddField.setEnabled(false);
        invZipField.setEnabled(false);
        invCityField.setEnabled(false);
        // Felder initial ausblenden
        invCompanyField.setVisible(false);
        invCompanyAddField.setVisible(false);
        invFirstnameField.setVisible(false);
        invLastnameField.setVisible(false);
        invStreetField.setVisible(false);
        invHouseNumberField.setVisible(false);
        invAddressAddField.setVisible(false);
        invZipField.setVisible(false);
        invCityField.setVisible(false);

        diffInvoiceAddress.addValueChangeListener(e -> {
            boolean enabled = e.getValue();
            invCompanyField.setEnabled(enabled);
            invCompanyAddField.setEnabled(enabled);
            invFirstnameField.setEnabled(enabled);
            invLastnameField.setEnabled(enabled);
            invStreetField.setEnabled(enabled);
            invHouseNumberField.setEnabled(enabled);
            invAddressAddField.setEnabled(enabled);
            // Sichtbarkeit an Checkbox koppeln
            invCompanyField.setVisible(enabled);
            invCompanyAddField.setVisible(enabled);
            invFirstnameField.setVisible(enabled);
            invLastnameField.setVisible(enabled);
            invStreetField.setVisible(enabled);
            invHouseNumberField.setVisible(enabled);
            invAddressAddField.setVisible(enabled);
            invZipField.setVisible(enabled);
            invCityField.setVisible(enabled);

            invZipField.setEnabled(enabled);
            invCityField.setEnabled(enabled);
        });

        // Formularfelder hinzufügen
        form.add(companyField, 2);
        form.add(companyAddField, 2);
        form.add(firstnameField, lastnameField);
        form.add(phoneField, faxField);
        form.add(mobileField, 2);
        form.add(emailField, 2);
        // Binder: Pflichtfelder und Bindings
        // Pflichtfelder markieren
        companyField.setRequiredIndicatorVisible(true);
        streetField.setRequiredIndicatorVisible(true);
        houseNumberField.setRequiredIndicatorVisible(true);
        zipField.setRequiredIndicatorVisible(true);
        cityField.setRequiredIndicatorVisible(true);

        // Hauptadresse binden
        binder.forField(companyField).asRequired("Firma ist erforderlich").bind(User::getCompany, User::setCompany);
        binder.forField(companyAddField).bind(User::getCompanyAddition, User::setCompanyAddition);
        binder.forField(streetField).asRequired("Straße ist erforderlich").bind(User::getStreet, User::setStreet);
        binder.forField(houseNumberField).asRequired("Hausnummer ist erforderlich").bind(User::getHouseNumber, User::setHouseNumber);
        binder.forField(addressAddField).bind(User::getAddressAddition, User::setAddressAddition);
        binder.forField(zipField).asRequired("Postleitzahl ist erforderlich").bind(User::getZip, User::setZip);
        binder.forField(cityField).asRequired("Stadt ist erforderlich").bind(User::getCity, User::setCity);

        // Personendaten binden
        binder.forField(firstnameField).asRequired("Vorname ist erforderlich").bind(User::getFirstname, User::setFirstname);
        binder.forField(lastnameField).asRequired("Nachname ist erforderlich").bind(User::getName, User::setName);
        binder.forField(phoneField).asRequired("Telefonnummer ist erforderlich").bind(User::getPhone, User::setPhone);
        binder.forField(emailField).asRequired("E-Mail ist erforderlich").withValidator(new EmailValidator("Ungültige E-Mail-Adresse"))
                .bind(User::getEmail, User::setEmail);
        // Optionale Felder
        binder.forField(mobileField).bind(User::getPhone2, User::setPhone2);
        binder.forField(faxField).bind(User::getFax, User::setFax);

        // Abweichende Rechnungsadresse binden
        binder.forField(diffInvoiceAddress).bind(
                User::isDiffInvoiceAddress,
                (user, value) -> user.setDiffInvoiceAddress(Boolean.TRUE.equals(value)));
        binder.forField(invCompanyField).bind(User::getInvCompany, User::setInvCompany);
        binder.forField(invCompanyAddField).bind(User::getInvCompanyAddition, User::setInvCompanyAddition);
        binder.forField(invFirstnameField).bind(User::getInvFirstname, User::setInvFirstname);
        binder.forField(invLastnameField).bind(User::getInvLastname, User::setInvLastname);
        binder.forField(invStreetField).bind(User::getInvStreet, User::setInvStreet);
        binder.forField(invHouseNumberField).bind(User::getInvHouseNumber, User::setInvHouseNumber);
        binder.forField(invAddressAddField).bind(User::getInvAddressAddition, User::setInvAddressAddition);
        binder.forField(invZipField).bind(User::getInvZip, User::setInvZip);
        binder.forField(invCityField).bind(User::getInvCity, User::setInvCity);
        // Pflichtindikator sichtbar machen
        firstnameField.setRequiredIndicatorVisible(true);
        lastnameField.setRequiredIndicatorVisible(true);
        phoneField.setRequiredIndicatorVisible(true);
        emailField.setRequiredIndicatorVisible(true);
        // Aktuellen Benutzer in die Felder laden
        binder.readBean(currentUser);

        form.add(streetField, houseNumberField);
        form.add(addressAddField, 2);
        form.add(zipField, cityField);
        form.add(diffInvoiceAddress, 2);
        form.add(invCompanyField, 2);
        form.add(invCompanyAddField, 2);
        // Tabs hinzufügen
        form.add(invFirstnameField, invLastnameField);
        form.add(invStreetField, invHouseNumberField);
        form.add(invAddressAddField, 2);
        form.add(invZipField, invCityField);

        tabSheet.add("Stammdaten", form);

        // Karte (2. Tab)
        Span coordsLabel = new Span("53°36'25.1\"N 10°06'46.9\"E");
        coordsLabel.getStyle().set("fontWeight", "bold").set("marginTop", "1em");
        Div mapDiv = new Div();
        mapDiv.setWidth("100%");
        mapDiv.setHeight("400px");
        mapDiv.getElement().setProperty("innerHTML",
                "<iframe width='100%' height='100%' frameborder='0' style='border:0' "
                        + "src='https://www.google.com/maps/embed/v1/place?key=AIzaSyDnbitL06iLp3elmj-WtPudCykX9xvXcVE&q=53.6070,10.1125' allowfullscreen></iframe>");
        VerticalLayout mapTab = new VerticalLayout();
        mapTab.setPadding(false);
        mapTab.setSpacing(true);
        mapTab.add(coordsLabel, mapDiv);
        tabSheet.add("Karte", mapTab);
        // Dritter Tab: Rechnungsstellung
        HorizontalLayout billingTab = new HorizontalLayout();
        billingTab.setWidthFull();
        billingTab.setSpacing(true);
        billingTab.setPadding(false);

        // Linke Spalte: Rechnungsbestandteile
        VerticalLayout billingLeft = new VerticalLayout();
        billingLeft.setWidth("45%");
        billingLeft.setPadding(false);
        billingLeft.setSpacing(true);
        H3 partsTitle = new H3("Rechnungsbestandteile");
        partsTitle.getStyle().set("margin", "0 0 var(--lumo-space-s) 0");

        // Felder für Rechnungsstellung (für Live-Update)
        billingEnabled = new Checkbox("Rechnungslegung über votianLT");
        billingEnabled.setValue(false);
        billingEnabled.addValueChangeListener(e -> toggleBilling(e.getValue()));

        prefixField = new TextField("Rechnungs Präfix");
        ustIdField = new TextField("USt-IdNr.");
        taxNumberField = new TextField("Steuernummer");
        bankNameField = new TextField("Bankname");
        ibanField = new TextField("IBAN");
        taxRateField = new TextField("Steuersatz");
        introTextArea = new TextArea("Einleitungstext");
        termsTextArea = new TextArea("Zahlungsbedingungen");
        introTextArea.setWidthFull();
        termsTextArea.setWidthFull();

        // Anfangszustand: Felder deaktiviert bis Checkbox aktiv
        setBillingFieldsEnabled(false);

        // Live-Update: EAGER und Listener
        prefixField.setValueChangeMode(ValueChangeMode.EAGER);
        ustIdField.setValueChangeMode(ValueChangeMode.EAGER);
        taxNumberField.setValueChangeMode(ValueChangeMode.EAGER);
        bankNameField.setValueChangeMode(ValueChangeMode.EAGER);
        ibanField.setValueChangeMode(ValueChangeMode.EAGER);
        taxRateField.setValueChangeMode(ValueChangeMode.EAGER);
        introTextArea.setValueChangeMode(ValueChangeMode.EAGER);
        termsTextArea.setValueChangeMode(ValueChangeMode.EAGER);
        prefixField.addValueChangeListener(e -> refreshPdf());
        ustIdField.addValueChangeListener(e -> refreshPdf());
        taxNumberField.addValueChangeListener(e -> refreshPdf());
        bankNameField.addValueChangeListener(e -> refreshPdf());
        ibanField.addValueChangeListener(e -> refreshPdf());
        taxRateField.addValueChangeListener(e -> refreshPdf());
        introTextArea.addValueChangeListener(e -> refreshPdf());
        termsTextArea.addValueChangeListener(e -> refreshPdf());

        billingLeft.add(partsTitle, billingEnabled, prefixField, ustIdField, taxNumberField, bankNameField, ibanField,
                taxRateField, introTextArea, termsTextArea);

        // Rechte Spalte: Vorschau
        VerticalLayout billingRight = new VerticalLayout();
        billingRight.setWidth("55%");
        billingRight.setPadding(false);
        billingRight.setSpacing(false);
        billingRight.setHeightFull();
        billingTab.setFlexGrow(1, billingRight);
        H3 previewTitle = new H3("Rechnungsvorschau");
        previewTitle.getStyle().set("margin", "0 0 var(--lumo-space-s) 0");

        // Echte PDF-Vorschau mittels StreamResource und iframe
        Div previewWrapper = new Div();
        previewWrapper.setWidth("100%");
        previewWrapper.setHeight("650px");
        previewWrapper.getStyle().set("overflow", "hidden").set("background", "var(--lumo-contrast-10pct)")
                .set("padding", "0");

        // Initial noch keine PDF laden (erst bei aktiver Checkbox)
        pdfFrame = new IFrame();
        pdfFrame.setWidth("99%");
        pdfFrame.setHeight("98%");
        pdfFrame.getStyle().set("border", "none");
        pdfFrame.getStyle().set("background", "var(--lumo-contrast-10pct)");
        previewWrapper.removeAll();
        previewWrapper.add(pdfFrame);

        billingRight.add(previewTitle, previewWrapper);

        billingTab.add(billingLeft, billingRight);
        tabSheet.add("Rechnungsstellung", billingTab);

        // Bestehende Rechnungsdaten laden (nach Erstellung aller Felder)
        loadInvoiceData();

        // Zweiter Tab: Einstellungen (Beispiel mit Schaltern)
        VerticalLayout switches = new VerticalLayout();
        switches.setPadding(false);
        switches.setSpacing(true);

        Checkbox digitalProcess = new Checkbox("Digitale Abwicklung per App");
        digitalProcess.setValue(currentUser.isDigitalProcessingEnabled());

        Span digitalProcessInfo = new Span("Aktiviert die digitale Auftragsabwicklung über die mobile App");
        digitalProcessInfo.getStyle().set("font-size", "var(--lumo-font-size-s)")
                                     .set("color", "var(--lumo-secondary-text-color)")
                                     .set("margin-left", "var(--lumo-space-xl)");

        Checkbox locateAppUser = new Checkbox("App-Nutzer orten");
        locateAppUser.setValue(currentUser.isLocationTrackingEnabled());

        Span locateAppUserInfo = new Span("Ermöglicht die Ortung von App-Nutzern während der Auftragsausführung");
        locateAppUserInfo.getStyle().set("font-size", "var(--lumo-font-size-s)")
                                     .set("color", "var(--lumo-secondary-text-color)")
                                     .set("margin-left", "var(--lumo-space-xl)");

        // Save checkbox states when changed
        digitalProcess.addValueChangeListener(e -> {
            currentUser.setDigitalProcessingEnabled(e.getValue());
        });

        locateAppUser.addValueChangeListener(e -> {
            currentUser.setLocationTrackingEnabled(e.getValue());
        });

        switches.add(digitalProcess, digitalProcessInfo, locateAppUser, locateAppUserInfo);
        tabSheet.add("Einstellungen", switches);

        // Sicherheit-Tab (2FA, Passwort, Konto)
        VerticalLayout securityTab = new VerticalLayout();
        securityTab.setPadding(false);
        securityTab.setSpacing(true);

        // 2-Faktor Auth
        Checkbox twoFactor = new Checkbox("2-Faktor-Authentifizierung");
        twoFactor.setValue(currentUser.isTwoFactorEnabled());
        twoFactor.addValueChangeListener(e -> currentUser.setTwoFactorEnabled(e.getValue()));
        Icon twoFactorInfo = VaadinIcon.QUESTION_CIRCLE_O.create();
        twoFactorInfo.getStyle().set("marginLeft", "0.3em");
        HorizontalLayout twoFactorLayout = new HorizontalLayout(twoFactor, twoFactorInfo);
        twoFactorLayout.setAlignItems(Alignment.CENTER);

        Span twoFactorDescription = new Span("Bei Aktivierung wird bei jeder Anmeldung ein Code per E-Mail gesendet");
        twoFactorDescription.getStyle().set("font-size", "var(--lumo-font-size-s)")
                                       .set("color", "var(--lumo-secondary-text-color)")
                                       .set("margin-left", "var(--lumo-space-xl)");

        securityTab.add(twoFactorLayout, twoFactorDescription);

        // Passwort ändern Button
        Button changePassword = new Button("Passwort ändern");
        changePassword.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        securityTab.add(changePassword);

        // Benutzerkonto löschen Button
        Button deleteAccount = new Button("Benutzerkonto löschen");
        deleteAccount.addThemeVariants(ButtonVariant.LUMO_ERROR);
        securityTab.add(deleteAccount);

        tabSheet.add("Konto", securityTab);

        // Profil speichern Button (unten rechts)
        Button saveProfile = new Button("Profiländerungen speichern");
        saveProfile.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        saveProfile.addClickListener(e -> {
            // Validate all required fields first
            boolean isValid = validateAllProfileFields(companyField, firstnameField, lastnameField, phoneField,
                                                        emailField, streetField, houseNumberField, zipField, cityField);

            if (!isValid) {
                Notification.show("Bitte füllen Sie alle Pflichtfelder korrekt aus", 3000, Notification.Position.MIDDLE);
                return;
            }

            if (binder.validate().isOk()) {
                try {
                    // Check if billing status changed
                    boolean oldBillingStatus = currentInvoiceData != null && currentInvoiceData.isBillingEnabled();
                    boolean newBillingStatus = billingEnabled.getValue();

                    binder.writeBean(currentUser);
                    userService.save(currentUser);
                    saveInvoiceData();
                    Notification.show("Profil gespeichert", 3000, Notification.Position.BOTTOM_END);

                    // Always reload if billing status changed to update the sidebar
                    if (oldBillingStatus != newBillingStatus) {
                        UI.getCurrent().getPage().reload();
                    }
                } catch (Exception ex) {
                    Notification.show("Fehler beim Speichern: " + ex.getMessage(), 4000, Notification.Position.MIDDLE);
                }
            }
        });
        // Tabs dem linken Bereich hinzufügen
        formColumn.add(tabSheet);

        // Button horizontal zentrieren unterhalb der Tabs
        HorizontalLayout buttonBar = new HorizontalLayout(saveProfile);
        buttonBar.setWidthFull();
        buttonBar.setJustifyContentMode(JustifyContentMode.CENTER);
        buttonBar.setPadding(false);
        buttonBar.setSpacing(false);
        // 20px Abstand nach oben
        buttonBar.getStyle().set("margin-top", "20px");
        // Fixieren am unteren Rand
        buttonBar.getStyle().set("position", "sticky");
        buttonBar.getStyle().set("bottom", "0");
        buttonBar.getStyle().set("background", "var(--lumo-base-color)");
        buttonBar.getStyle().set("padding", "var(--lumo-space-s) 0");
        buttonBar.getStyle().set("z-index", "1");
        formColumn.add(buttonBar);
        add(formColumn);
    }

    // PDF neu rendern und iframe aktualisieren
    // Felder im Billing-Tab aktivieren/deaktivieren
    private void setBillingFieldsEnabled(boolean enabled) {
        if (prefixField != null)
            prefixField.setEnabled(enabled);
        if (ustIdField != null)
            ustIdField.setEnabled(enabled);
        if (taxNumberField != null)
            taxNumberField.setEnabled(enabled);
        if (bankNameField != null)
            bankNameField.setEnabled(enabled);
        if (ibanField != null)
            ibanField.setEnabled(enabled);
        if (taxRateField != null)
            taxRateField.setEnabled(enabled);
        if (introTextArea != null)
            introTextArea.setEnabled(enabled);
        if (termsTextArea != null)
            termsTextArea.setEnabled(enabled);
    }

    // Checkbox steuert Aktivierung und PDF
    private void toggleBilling(boolean enabled) {
        setBillingFieldsEnabled(enabled);
        if (enabled) {
            refreshPdf();
        } else {
            if (pdfFrame != null) {
                pdfFrame.setSrc("about:blank");
            }
        }
        // Sicherstellen, dass das IFrame den verfügbaren Raum nutzt
        if (pdfFrame != null) {
            pdfFrame.setWidth("100%");
            pdfFrame.setHeight("100%");
            pdfFrame.getStyle().set("border", "none");
            pdfFrame.getStyle().set("display", "block");
        }
    }

    private void refreshPdf() {
        try {
            byte[] bytes = generatePreviewPdf();
            if (bytes != null && bytes.length > 0) {
                String dataUrl = "data:application/pdf;base64," + Base64.getEncoder().encodeToString(bytes)
                        + "#toolbar=0&navpanes=0&statusbar=0&view=Fit&zoom=page-fit";
                if (pdfFrame != null) {
                    pdfFrame.setSrc(dataUrl);
                }
            }
        } catch (Exception e) {
            // Log error or show notification
            Notification.show("Fehler bei PDF-Generierung: " + e.getMessage(), 3000, Notification.Position.BOTTOM_END);
        }
    }

    private byte[] generatePreviewPdf() {
        try {
            // Create CustomerInvoiceData with user's billing information
            CustomerInvoiceData invoiceData = new CustomerInvoiceData();

            // Set invoice details
            String invoiceNumber = safe(prefixField) + "-" + System.currentTimeMillis();
            invoiceData.setInvoiceNumber(invoiceNumber);
            invoiceData.setInvoiceDate(LocalDate.now());
            invoiceData.setDeliveryDate(LocalDate.now());
            invoiceData.setDescription(safe(introTextArea));

            // Set sender details from user profile and invoice settings
            String companyName = safe(currentUser.getCompany());
            if (companyName.isEmpty()) {
                companyName = safe(currentUser.getFirstname()) + " " + safe(currentUser.getName());
            }
            invoiceData.setSenderName(companyName);
            invoiceData.setSenderAddress(safe(currentUser.getStreet()) + " " + safe(currentUser.getHouseNumber()));
            invoiceData.setSenderPostcode(safe(currentUser.getZip()));
            invoiceData.setSenderCity(safe(currentUser.getCity()));
            invoiceData.setSenderCountry("Deutschland");
            invoiceData.setSenderTaxNumber(safe(taxNumberField));
            invoiceData.setSenderVatId(safe(ustIdField));
            invoiceData.setSenderPhone(safe(currentUser.getPhone()));
            invoiceData.setSenderEmail(safe(currentUser.getEmail()));
            invoiceData.setSenderWebsite("");

            // Set recipient details (example data for preview)
            invoiceData.setRecipientName("Max Mustermann");
            invoiceData.setRecipientCompany("Musterfirma GmbH");
            invoiceData.setRecipientAddress("Beispielstraße 123");
            invoiceData.setRecipientPostcode("12345");
            invoiceData.setRecipientCity("Beispielstadt");
            invoiceData.setRecipientCountry("Deutschland");
            invoiceData.setRecipientVatId("DE123456789");

            // Create sample invoice items for preview
            List<CustomerInvoiceItem> items = new ArrayList<>();
            BigDecimal vatRate = parseVatRate(safe(taxRateField));

            CustomerInvoiceItem item1 = new CustomerInvoiceItem(
                new BigDecimal("1"), "Stk.", "Beispiel-Dienstleistung 1",
                new BigDecimal("100.00"), vatRate);
            CustomerInvoiceItem item2 = new CustomerInvoiceItem(
                new BigDecimal("2"), "Std.", "Beispiel-Dienstleistung 2",
                new BigDecimal("50.00"), vatRate);

            items.add(item1);
            items.add(item2);
            invoiceData.setItems(items);

            // Calculate amounts
            BigDecimal netAmount = items.stream()
                .map(CustomerInvoiceItem::getNetTotal)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal vatAmount = netAmount.multiply(vatRate);
            BigDecimal totalAmount = netAmount.add(vatAmount);

            invoiceData.setNetAmount(netAmount);
            invoiceData.setVatRate(vatRate);
            invoiceData.setVatAmount(vatAmount);
            invoiceData.setTotalAmount(totalAmount);

            // Set payment details
            invoiceData.setPaymentTerms(safe(termsTextArea));
            invoiceData.setPaymentDueDate(LocalDate.now().plusDays(14));
            invoiceData.setBankAccount(safe(bankNameField));
            invoiceData.setIban(safe(ibanField));
            invoiceData.setBic("");

            // Legal notes
            invoiceData.setLegalNotes("");

            // Generate PDF using CustomerInvoiceService
            return customerInvoiceService.generateCustomerInvoicePdf(invoiceData);

        } catch (Exception e) {
            e.printStackTrace();
            // Return empty PDF on error
            return new byte[0];
        }
    }

    private BigDecimal parseVatRate(String taxRateStr) {
        try {
            if (taxRateStr == null || taxRateStr.isEmpty()) {
                return new BigDecimal("0.19"); // Default 19%
            }
            // Remove % sign if present and convert to decimal
            taxRateStr = taxRateStr.replace("%", "").trim();
            BigDecimal rate = new BigDecimal(taxRateStr);
            // If value is greater than 1, assume it's a percentage and convert
            if (rate.compareTo(BigDecimal.ONE) > 0) {
                rate = rate.divide(new BigDecimal("100"));
            }
            return rate;
        } catch (Exception e) {
            return new BigDecimal("0.19"); // Default 19% on error
        }
    }

    // Utility: safe getter für TextField/TextArea
    private String safe(TextField f) {
        return f != null && f.getValue() != null ? f.getValue() : "";
    }

    private String safe(TextArea f) {
        return f != null && f.getValue() != null ? f.getValue() : "";
    }

    private void loadInvoiceData() {
        currentInvoiceData = userInvoiceDataService.findByUserId(currentUser.getId()).orElse(null);

        if (currentInvoiceData != null) {
            billingEnabled.setValue(currentInvoiceData.isBillingEnabled());
            prefixField.setValue(safe(currentInvoiceData.getPrefix()));
            ustIdField.setValue(safe(currentInvoiceData.getUstId()));
            taxNumberField.setValue(safe(currentInvoiceData.getTaxNumber()));
            bankNameField.setValue(safe(currentInvoiceData.getBankName()));
            ibanField.setValue(safe(currentInvoiceData.getIban()));
            taxRateField.setValue(safe(currentInvoiceData.getTaxRate()));
            introTextArea.setValue(safe(currentInvoiceData.getIntroText()));
            termsTextArea.setValue(safe(currentInvoiceData.getPaymentTerms()));

            // Update field enabled state and PDF preview based on loaded state
            setBillingFieldsEnabled(currentInvoiceData.isBillingEnabled());
            if (currentInvoiceData.isBillingEnabled()) {
                refreshPdf();
            }
        }
    }

    private void saveInvoiceData() {
        currentInvoiceData = userInvoiceDataService.createOrUpdate(
            currentUser.getId(),
            billingEnabled.getValue(),
            prefixField.getValue(),
            ustIdField.getValue(),
            taxNumberField.getValue(),
            bankNameField.getValue(),
            ibanField.getValue(),
            taxRateField.getValue(),
            introTextArea.getValue(),
            termsTextArea.getValue()
        );
    }

    private String safe(String value) {
        return value != null ? value : "";
    }

    private void validateField(TextField field, String errorMessage) {
        String value = field.getValue();
        if (value == null || value.trim().isEmpty()) {
            field.setInvalid(true);
            field.setErrorMessage(errorMessage);
        } else {
            field.setInvalid(false);
            field.setErrorMessage("");
        }
    }

    private void validateEmailField(EmailField emailField) {
        String value = emailField.getValue();
        if (value == null || value.trim().isEmpty()) {
            emailField.setInvalid(true);
            emailField.setErrorMessage("E-Mail-Adresse ist ein Pflichtfeld");
        } else if (!value.contains("@") || !value.contains(".")) {
            emailField.setInvalid(true);
            emailField.setErrorMessage("Bitte geben Sie eine gültige E-Mail-Adresse ein");
        } else {
            emailField.setInvalid(false);
            emailField.setErrorMessage("");
        }
    }

    private boolean validateAllProfileFields(TextField companyField, TextField firstnameField, TextField lastnameField,
                                             TextField phoneField, EmailField emailField, TextField streetField,
                                             TextField houseNumberField, TextField zipField, TextField cityField) {
        validateField(companyField, "Firma ist ein Pflichtfeld");
        validateField(firstnameField, "Vorname ist ein Pflichtfeld");
        validateField(lastnameField, "Nachname ist ein Pflichtfeld");
        validateField(phoneField, "Telefonnummer ist ein Pflichtfeld");
        validateEmailField(emailField);
        validateField(streetField, "Straße ist ein Pflichtfeld");
        validateField(houseNumberField, "Hausnummer ist ein Pflichtfeld");
        validateField(zipField, "Postleitzahl ist ein Pflichtfeld");
        validateField(cityField, "Stadt ist ein Pflichtfeld");

        return !companyField.isInvalid() && !firstnameField.isInvalid() && !lastnameField.isInvalid()
                && !phoneField.isInvalid() && !emailField.isInvalid() && !streetField.isInvalid()
                && !houseNumberField.isInvalid() && !zipField.isInvalid() && !cityField.isInvalid();
    }

}
