package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.button.Button;
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;
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.dialog.Dialog;
import com.vaadin.flow.component.html.IFrame;
import com.vaadin.flow.component.html.Input;
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.math.RoundingMode;
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.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.validator.EmailValidator;
import com.vaadin.flow.router.HasDynamicTitle;
import com.vaadin.flow.router.Route;
import de.assecutor.votianlt.model.Language;
import de.assecutor.votianlt.model.User;
import de.assecutor.votianlt.model.Service;
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.repository.ServiceRepository;
import de.assecutor.votianlt.security.SecurityService;
import de.assecutor.votianlt.service.CustomerInvoiceService;
import de.assecutor.votianlt.service.InvoiceTemplateService;
import de.assecutor.votianlt.service.LanguageService;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.ClientCallable;
import jakarta.annotation.security.RolesAllowed;
import de.assecutor.votianlt.pages.base.ui.component.DialogStylingHelper;

@Route(value = "edit-profile", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER", "ADMIN" })
@JsModule("./invoice-generator/profile-invoice-generator.js")
public class EditProfileView extends HorizontalLayout implements HasDynamicTitle {
    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 final InvoiceTemplateService invoiceTemplateService;
    private UserInvoiceData currentInvoiceData;
    private Checkbox billingEnabled;
    private NumberField vatRateField;
    private VerticalLayout propertiesPanelProfile;

    private final ServiceRepository serviceRepository;
    private Grid<Service> servicesGrid;

    // Store the original language from the database
    private final Language originalLanguage;

    public EditProfileView(UserService userService, UserInvoiceDataService userInvoiceDataService,
            CustomerInvoiceService customerInvoiceService, InvoiceTemplateService invoiceTemplateService,
            LanguageService languageService, SecurityService securityService, ServiceRepository serviceRepository) {
        this.userInvoiceDataService = userInvoiceDataService;
        this.customerInvoiceService = customerInvoiceService;
        this.invoiceTemplateService = invoiceTemplateService;
        this.currentUser = securityService.getCurrentDatabaseUser();
        this.serviceRepository = serviceRepository;

        // Store the original language before any changes
        this.originalLanguage = this.currentUser != null ? this.currentUser.getLanguage() : Language.DE;
        setSizeFull();
        setPadding(true);
        setSpacing(true);
        addClassName("form-page");
        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.setWidthFull();
        formColumn.setHeightFull();
        formColumn.setPadding(false);
        formColumn.setSpacing(false);

        ViewToolbar toolbar = new ViewToolbar(getTranslation("page.title.profile.edit"));
        formColumn.add(toolbar);

        // 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(getTranslation("profile.company"));
        companyField.addBlurListener(e -> validateField(companyField, getTranslation("profile.validation.company")));

        TextField companyAddField = new TextField(getTranslation("profile.companyadd"));

        TextField firstnameField = new TextField(getTranslation("profile.firstname"));
        firstnameField
                .addBlurListener(e -> validateField(firstnameField, getTranslation("profile.validation.firstname")));

        TextField lastnameField = new TextField(getTranslation("profile.lastname"));
        lastnameField.addBlurListener(e -> validateField(lastnameField, getTranslation("profile.validation.lastname")));

        TextField phoneField = new TextField(getTranslation("profile.phone"));
        phoneField.addBlurListener(e -> validateField(phoneField, getTranslation("profile.validation.phone")));

        TextField faxField = new TextField(getTranslation("profile.fax"));
        TextField mobileField = new TextField(getTranslation("profile.mobile"));

        EmailField emailField = new EmailField(getTranslation("profile.email"));
        emailField.addBlurListener(e -> validateEmailField(emailField));

        TextField streetField = new TextField(getTranslation("profile.street"));
        streetField.addBlurListener(e -> validateField(streetField, getTranslation("profile.validation.street")));

        TextField houseNumberField = new TextField(getTranslation("profile.housenr"));
        houseNumberField
                .addBlurListener(e -> validateField(houseNumberField, getTranslation("profile.validation.housenr")));

        TextField addressAddField = new TextField(getTranslation("profile.addressadd"));

        TextField zipField = new TextField(getTranslation("profile.zip"));
        zipField.addBlurListener(e -> validateField(zipField, getTranslation("profile.validation.zip")));

        TextField cityField = new TextField(getTranslation("profile.city"));
        cityField.addBlurListener(e -> validateField(cityField, getTranslation("profile.validation.city")));

        // Abweichende Rechnungsadresse
        Checkbox diffInvoiceAddress = new Checkbox(getTranslation("profile.diffinvoice"));
        diffInvoiceAddress.getStyle().set("marginTop", "1em");
        // Rechnungsadresse Felder (disabled by default)
        TextField invCompanyField = new TextField(getTranslation("profile.company"));
        TextField invCompanyAddField = new TextField(getTranslation("profile.companyadd"));
        TextField invFirstnameField = new TextField(getTranslation("profile.firstname"));
        TextField invLastnameField = new TextField(getTranslation("profile.lastname"));
        TextField invStreetField = new TextField(getTranslation("profile.street"));
        TextField invHouseNumberField = new TextField(getTranslation("profile.housenr"));
        TextField invAddressAddField = new TextField(getTranslation("profile.addressadd"));
        TextField invZipField = new TextField(getTranslation("profile.zip"));
        TextField invCityField = new TextField(getTranslation("profile.city"));
        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(getTranslation("profile.validation.company.required"))
                .bind(User::getCompany, User::setCompany);
        binder.forField(companyAddField).bind(User::getCompanyAddition, User::setCompanyAddition);
        binder.forField(streetField).asRequired(getTranslation("profile.validation.street.required"))
                .bind(User::getStreet, User::setStreet);
        binder.forField(houseNumberField).asRequired(getTranslation("profile.validation.housenr.required"))
                .bind(User::getHouseNumber, User::setHouseNumber);
        binder.forField(addressAddField).bind(User::getAddressAddition, User::setAddressAddition);
        binder.forField(zipField).asRequired(getTranslation("profile.validation.zip.required")).bind(User::getZip,
                User::setZip);
        binder.forField(cityField).asRequired(getTranslation("profile.validation.city.required")).bind(User::getCity,
                User::setCity);

        // Personendaten binden
        binder.forField(firstnameField).asRequired(getTranslation("profile.validation.firstname.required"))
                .bind(User::getFirstname, User::setFirstname);
        binder.forField(lastnameField).asRequired(getTranslation("profile.validation.lastname.required"))
                .bind(User::getName, User::setName);
        binder.forField(phoneField).asRequired(getTranslation("profile.validation.phone.required")).bind(User::getPhone,
                User::setPhone);
        binder.forField(emailField).asRequired(getTranslation("profile.validation.email.required"))
                .withValidator(new EmailValidator(getTranslation("profile.validation.email.invalid")))
                .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(getTranslation("profile.basicdata"), 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(getTranslation("profile.map"), mapTab);
        // Dritter Tab: Rechnungserstellung
        VerticalLayout billingTab = new VerticalLayout();
        billingTab.setWidthFull();
        billingTab.setSpacing(true);
        billingTab.setPadding(false);
        billingTab.setHeightFull();

        // Rechnungsfelder initialisieren (für Speicherung, aber nicht im UI)
        prefixField = new TextField();
        ustIdField = new TextField();
        taxNumberField = new TextField();
        bankNameField = new TextField();
        ibanField = new TextField();
        taxRateField = new TextField();
        taxRateField.setValue("19");
        introTextArea = new TextArea();
        termsTextArea = new TextArea();
        pdfFrame = new IFrame();

        // Checkbox "Rechnungslegung über votianLT"
        billingEnabled = new Checkbox(getTranslation("profile.billing.enabled"));
        billingEnabled.setValue(true); // Standardmäßig aktiviert

        prefixField.setLabel(getTranslation("profile.billing.prefix"));
        prefixField.setPlaceholder("z.B. RE-2024-");
        prefixField.setMaxWidth("300px");
        prefixField.setVisible(true);
        prefixField.addBlurListener(e -> {
            saveInvoiceData();
            String p = prefixField.getValue();
            String invNr = (p != null && !p.isBlank() ? p : "") + "12345";
            getElement().executeJs(
                    "if (window.updateProfileMasterdataValue) { window.updateProfileMasterdataValue('masterdata.invoice_number', '"
                            + invNr.replace("'", "\\'") + "'); }");
        });

        vatRateField = new NumberField();
        vatRateField.setLabel(getTranslation("profile.settings.vatrate"));
        vatRateField.setSuffixComponent(new Span("%"));
        vatRateField.setStep(0.01);
        vatRateField.setMin(0);
        vatRateField.setMaxWidth("200px");
        if (currentUser.getVatRate() != null) {
            vatRateField.setValue(currentUser.getVatRate().multiply(new java.math.BigDecimal("100")).doubleValue());
        }
        vatRateField.addValueChangeListener(e -> {
            Double v = e.getValue();
            if (v != null) {
                currentUser.setVatRate(new java.math.BigDecimal(Double.toString(v))
                        .divide(new java.math.BigDecimal("100"), 4, java.math.RoundingMode.HALF_UP));
                getElement().executeJs("if (window.updateProfileVatRate) { window.updateProfileVatRate($0); }",
                        v / 100.0);
            }
        });

        HorizontalLayout billingHeaderLayout = new HorizontalLayout(billingEnabled, prefixField, vatRateField);
        billingHeaderLayout.setSpacing(true);
        billingHeaderLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
        billingTab.add(billingHeaderLayout);

        // Steuer- und Bankdaten: Pflichtangaben nach §14 UStG bzw. für die
        // ZUGFeRD-E-Rechnung (Absender-USt-IdNr./Steuernummer, IBAN)
        ustIdField.setLabel(getTranslation("profile.billing.ustid"));
        ustIdField.setPlaceholder("DE123456789");
        ustIdField.addBlurListener(e -> saveInvoiceData());
        taxNumberField.setLabel(getTranslation("profile.billing.taxnumber"));
        taxNumberField.addBlurListener(e -> saveInvoiceData());
        bankNameField.setLabel(getTranslation("profile.billing.bankname"));
        bankNameField.addBlurListener(e -> saveInvoiceData());
        ibanField.setLabel(getTranslation("profile.billing.iban"));
        ibanField.setPlaceholder("DE00 0000 0000 0000 0000 00");
        ibanField.addBlurListener(e -> saveInvoiceData());

        HorizontalLayout billingTaxLayout = new HorizontalLayout(ustIdField, taxNumberField, bankNameField, ibanField);
        billingTaxLayout.setSpacing(true);
        billingTaxLayout.setAlignItems(FlexComponent.Alignment.BASELINE);
        billingTab.add(billingTaxLayout);

        // Hauptlayout: Links (Templates) | Mitte (Canvas) | Rechts (Eigenschaften)
        final HorizontalLayout mainLayout = new HorizontalLayout();
        mainLayout.setWidthFull();
        mainLayout.setHeight("500px");
        mainLayout.setSpacing(true);
        mainLayout.getStyle().set("overflow", "hidden");

        // Linke Seite: Templates/Bausteine
        VerticalLayout leftPanel = createTemplatesPanelForProfile();
        leftPanel.setWidth("220px");
        leftPanel.setHeightFull();
        leftPanel.getStyle().set("flex-shrink", "0").set("min-width", "220px").set("overflow", "auto")
                .set("background-color", "var(--lumo-contrast-5pct)")
                .set("border-radius", "var(--lumo-border-radius-m)").set("padding", "var(--lumo-space-m)");

        // Mitte: Canvas
        Div canvasContainer = new Div();
        canvasContainer.setId("invoice-canvas-container-profile");
        canvasContainer.setWidth("100%");
        canvasContainer.setHeight("100%");
        canvasContainer.getStyle().set("background-color", "#e8e8e8")
                .set("border", "1px solid var(--lumo-contrast-20pct)")
                .set("border-radius", "var(--lumo-border-radius-m)").set("overflow", "hidden")
                .set("position", "relative");

        VerticalLayout centerPanel = new VerticalLayout();
        centerPanel.setWidth("60%");
        centerPanel.setHeightFull();
        centerPanel.setPadding(false);
        centerPanel.setSpacing(false);
        centerPanel.getStyle().set("flex-grow", "1").set("min-width", "0");
        centerPanel.add(canvasContainer);
        centerPanel.expand(canvasContainer);

        // Rechte Seite: Eigenschaften
        propertiesPanelProfile = createPropertiesPanelForProfile();
        propertiesPanelProfile.setWidth("280px");
        propertiesPanelProfile.setHeightFull();
        propertiesPanelProfile.getStyle().set("flex-shrink", "0").set("min-width", "280px").set("overflow", "auto")
                .set("background-color", "var(--lumo-contrast-5pct)")
                .set("border-radius", "var(--lumo-border-radius-m)").set("padding", "var(--lumo-space-m)");

        mainLayout.add(leftPanel, centerPanel, propertiesPanelProfile);
        mainLayout.expand(centerPanel);
        billingTab.add(mainLayout);
        billingTab.expand(mainLayout);

        // Initialen Zustand setzen (sichtbar da checkbox standardmäßig true)
        mainLayout.setVisible(true);

        // Action Buttons für den Rechnungsgenerator
        final HorizontalLayout actionLayout = new HorizontalLayout();
        actionLayout.setWidthFull();
        actionLayout.setJustifyContentMode(JustifyContentMode.END);
        actionLayout.setSpacing(true);
        actionLayout.getStyle().set("margin-top", "var(--lumo-space-s)");

        Button undoButton = new Button(getTranslation("button.undo"), new Icon(VaadinIcon.ARROW_BACKWARD));
        undoButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
        undoButton.addClickListener(
                e -> getElement().executeJs("if (window.undoProfileCanvas) { window.undoProfileCanvas(); }"));

        Button previewPdfButton = new Button(getTranslation("button.preview"), new Icon(VaadinIcon.EYE));
        previewPdfButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_SUCCESS);
        previewPdfButton.addClickListener(e -> generatePreviewPdfFromProfile());

        Button saveTemplateButton = new Button(getTranslation("button.savetemplate"), new Icon(VaadinIcon.DOWNLOAD));
        saveTemplateButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        saveTemplateButton.addClickListener(e -> {
            getElement().executeJs(
                    "if (window.getProfileCanvasData) { return JSON.stringify(window.getProfileCanvasData()); } else { return null; }")
                    .then(result -> {
                        if (result == null) {
                            Notification.show(getTranslation("profile.canvas.read.error"), 3000,
                                    Notification.Position.BOTTOM_CENTER);
                            return;
                        }
                        try {
                            String templateData;
                            if (result instanceof elemental.json.JsonValue) {
                                elemental.json.JsonValue jsonValue = (elemental.json.JsonValue) result;
                                templateData = jsonValue.toJson();
                            } else {
                                templateData = result.toString();
                            }
                            invoiceTemplateService.saveTemplate(currentUser.getId().toString(), templateData);
                            Notification.show(getTranslation("profile.template.saved"), 3000,
                                    Notification.Position.BOTTOM_CENTER);
                        } catch (Exception ex) {
                            Notification.show(getTranslation("profile.save.error", ex.getMessage()), 5000,
                                    Notification.Position.BOTTOM_CENTER);
                        }
                    });
        });

        actionLayout.add(undoButton, previewPdfButton, saveTemplateButton);
        billingTab.add(actionLayout);

        // Initialen Zustand setzen (sichtbar da checkbox standardmäßig true)
        actionLayout.setVisible(true);

        tabSheet.add(getTranslation("profile.invoicecreation"), billingTab);

        // Sichtbarkeit des Invoice Generators an Checkbox binden
        billingEnabled.addValueChangeListener(e -> {
            boolean visible = e.getValue();
            prefixField.setVisible(visible);
            vatRateField.setVisible(visible);
            mainLayout.setVisible(visible);
            actionLayout.setVisible(visible);
        });

        // Bestehende Rechnungsdaten laden (nur für die Checkbox)
        loadInvoiceData();

        // Initialize invoice generator when the billing tab is selected
        // Also register this view instance for JavaScript callbacks
        tabSheet.addSelectedChangeListener(e -> {
            if (getTranslation("profile.invoicecreation").equals(e.getSelectedTab().getLabel())) {
                getElement().executeJs("window.invoiceGeneratorViewProfile = $0;"
                        + "window.profileInvoiceServiceData = null;" + "setTimeout(function() { "
                        + "  if (window.initProfileInvoiceGenerator) { " + "    window.initProfileInvoiceGenerator(); "
                        + "    console.log('Canvas initialized, now loading template...'); "
                        + "    setTimeout(function() { " + "      $0.$server.onCanvasReady(); " + "    }, 200); "
                        + "  } else { " + "    console.error('initProfileInvoiceGenerator not found'); " + "  } "
                        + "}, 300);", getElement());
            }
        });

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

        Checkbox digitalProcess = new Checkbox(getTranslation("profile.settings.digitalprocess"));
        digitalProcess.setValue(currentUser.isDigitalProcessingEnabled());

        Span digitalProcessInfo = new Span(getTranslation("profile.settings.digitalprocess.info"));
        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(getTranslation("profile.settings.locateappuser"));
        locateAppUser.setValue(currentUser.isLocationTrackingEnabled());

        Span locateAppUserInfo = new Span(getTranslation("profile.settings.locateappuser.info"));
        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(getTranslation("profile.settings"), switches);

        // Spracheinstellung unter Einstellungen
        HorizontalLayout languageLayout = new HorizontalLayout();
        languageLayout.setWidthFull();
        languageLayout.setSpacing(true);
        languageLayout.setAlignItems(FlexComponent.Alignment.CENTER);

        // Sprache Label
        Span languageLabel = new Span(getTranslation("profile.language"));
        languageLabel.getStyle().set("font-size", "var(--lumo-font-size-m)").set("font-weight", "500");

        // ComboBox mit Flaggen-Icons
        ComboBox<Language> languageCombo = new ComboBox<>();
        languageCombo.setWidth("200px");
        languageCombo.setItems(Language.values());
        languageCombo.setItemLabelGenerator(language -> {
            // Flaggen-Emoji für jede Sprache
            String flag = switch (language) {
            case DE -> "🇩🇪 ";
            case EN -> "🇬🇧 ";
            case FR -> "🇫🇷 ";
            case ES -> "🇪🇸 ";
            case TR -> "🇹🇷 ";
            case PL -> "🇵🇱 ";
            case RU -> "🇷🇺 ";
            case EE -> "🇪🇪 ";
            case LV -> "🇱🇻 ";
            case LT -> "🇱🇹 ";
            };
            return flag + language.getDisplayName();
        });
        languageCombo.setValue(currentUser.getLanguage());

        // Store the selected language temporarily, but don't save yet
        languageCombo.addValueChangeListener(e -> {
            // Language will be saved when the user clicks save button
            currentUser.setLanguage(e.getValue());

            // Also set the language cookie so it's available before login
            setLanguageCookie(e.getValue());
        });

        languageLayout.add(languageLabel, languageCombo);
        switches.add(languageLayout);

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

        // 2-Faktor Auth
        Checkbox twoFactor = new Checkbox(getTranslation("profile.security.twofactor"));
        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(getTranslation("profile.security.twofactor.info"));
        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(getTranslation("button.changepassword"));
        changePassword.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        securityTab.add(changePassword);

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

        tabSheet.add(getTranslation("profile.account"), securityTab);

        // Leistungskatalog Tab
        VerticalLayout servicesTab = createServicesTab();
        tabSheet.add(getTranslation("profile.services"), servicesTab);

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

            if (!isValid) {
                Notification.show(getTranslation("profile.validation.required.fill"), 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(getTranslation("profile.saved"), 3000, Notification.Position.BOTTOM_END);

                    // Check if language changed (compare with original language from database)
                    boolean languageChanged = originalLanguage != currentUser.getLanguage();

                    // Reload if billing status changed or language changed
                    if (oldBillingStatus != newBillingStatus || languageChanged) {
                        UI.getCurrent().getPage().reload();
                    }
                } catch (Exception ex) {
                    Notification.show(getTranslation("profile.save.error", 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", "transparent");
        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 (introTextArea != null)
            introTextArea.setEnabled(enabled);
        if (termsTextArea != null)
            termsTextArea.setEnabled(enabled);
    }

    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(getTranslation("profile.pdf.error", 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 = Service.FIXED_VAT_RATE;

            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];
        }
    }

    // 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("19");
            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(), "19", 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(getTranslation("profile.validation.email.required"));
        } else if (!value.contains("@") || !value.contains(".")) {
            emailField.setInvalid(true);
            emailField.setErrorMessage(getTranslation("profile.validation.email.invalid"));
        } 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, getTranslation("profile.validation.company"));
        validateField(firstnameField, getTranslation("profile.validation.firstname"));
        validateField(lastnameField, getTranslation("profile.validation.lastname"));
        validateField(phoneField, getTranslation("profile.validation.phone"));
        validateEmailField(emailField);
        validateField(streetField, getTranslation("profile.validation.street"));
        validateField(houseNumberField, getTranslation("profile.validation.housenr"));
        validateField(zipField, getTranslation("profile.validation.zip"));
        validateField(cityField, getTranslation("profile.validation.city"));

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

    private BigDecimal getPreviewVatRate() {
        if (vatRateField != null && vatRateField.getValue() != null) {
            return new BigDecimal(Double.toString(vatRateField.getValue())).divide(new BigDecimal("100"), 4,
                    java.math.RoundingMode.HALF_UP);
        }
        if (currentUser != null && currentUser.getVatRate() != null) {
            return currentUser.getVatRate();
        }
        return Service.FIXED_VAT_RATE;
    }

    // Methoden für den Rechnungsgenerator im Profil
    private void generatePreviewPdfFromProfile() {
        try {
            getElement().executeJs(
                    "if (window.getProfileCanvasData) { return window.getProfileCanvasData(); } else { return null; }")
                    .then(result -> {
                        if (result == null) {
                            Notification.show(getTranslation("profile.canvas.read.error"), 3000,
                                    Notification.Position.BOTTOM_CENTER);
                            return;
                        }
                        try {
                            String templateData;
                            if (result instanceof elemental.json.JsonValue) {
                                elemental.json.JsonValue jsonValue = (elemental.json.JsonValue) result;
                                templateData = jsonValue.toJson();
                            } else {
                                templateData = result.toString();
                            }
                            BigDecimal previewVatRate = getPreviewVatRate();
                            byte[] pdfBytes = customerInvoiceService.generatePdfFromCanvasTemplate(templateData,
                                    currentUser, prefixField.getValue(), previewVatRate);
                            showPdfInDialog(pdfBytes);
                        } catch (Exception ex) {
                            Notification.show(getTranslation("profile.invoice.pdf.preview.error", ex.getMessage()),
                                    3000, Notification.Position.BOTTOM_CENTER);
                        }
                    });
        } catch (Exception ex) {
            Notification.show(getTranslation("profile.error", ex.getMessage()), 3000,
                    Notification.Position.BOTTOM_CENTER);
        }
    }

    private void showPdfInDialog(byte[] pdfBytes) {
        // Create a stream resource for the PDF
        String base64Pdf = Base64.getEncoder().encodeToString(pdfBytes);
        String dataUrl = "data:application/pdf;base64," + base64Pdf;

        // Create dialog
        Dialog pdfDialog = DialogStylingHelper.createStyledDialog(getTranslation("profile.invoice.pdf.preview"), "90vw");
        pdfDialog.setHeight("90vh");

        // Create a Div to hold the PDF viewer
        Div pdfContainer = new Div();
        pdfContainer.setWidth("100%");
        pdfContainer.setHeight("100%");
        pdfContainer.getStyle().set("display", "flex").set("flex-direction", "column").set("overflow", "hidden");

        // Use an iframe with data URL for PDF display
        IFrame pdfFrame = new IFrame();
        pdfFrame.setWidth("100%");
        pdfFrame.setHeight("100%");
        pdfFrame.getElement().setAttribute("src", dataUrl);
        pdfFrame.getStyle().set("border", "none").set("flex-grow", "1");

        pdfContainer.add(pdfFrame);

        // Close button
        Button closeButton = new Button(getTranslation("button.close"), e -> pdfDialog.close());
        closeButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        // Download button
        Button downloadButton = new Button(getTranslation("button.download"), e -> {
            getElement()
                    .executeJs("const link = document.createElement('a');" + "link.href = 'data:application/pdf;base64,"
                            + base64Pdf + "';" + "link.download = 'vorschau.pdf';" + "link.click();");
        });
        downloadButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);

        pdfDialog.add(DialogStylingHelper.wrapContent(pdfContainer, true));
        pdfDialog.getFooter().add(downloadButton, closeButton);
        pdfDialog.open();
    }

    // Panel-Methoden für den Rechnungsgenerator
    private VerticalLayout createTemplatesPanelForProfile() {
        VerticalLayout panel = new VerticalLayout();
        panel.setPadding(false);
        panel.setSpacing(true);
        panel.setHeightFull();

        // Bereich 1: Meine Stammdaten
        Span invoiceHeader = new Span(getTranslation("profile.invoice.masterdata"));
        invoiceHeader.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-m)")
                .set("margin-top", "var(--lumo-space-s)");

        // Stammdaten als Variablen - mit tatsächlichen Werten aus currentUser
        String company = safe(currentUser.getCompany());
        String fullName = safe(currentUser.getFirstname()) + " " + safe(currentUser.getName());
        String street = safe(currentUser.getStreet()) + " " + safe(currentUser.getHouseNumber());
        String city = safe(currentUser.getZip()) + " " + safe(currentUser.getCity());
        String email = safe(currentUser.getEmail());
        String phone = safe(currentUser.getPhone());

        Div senderCompany = createVariableTemplate(getTranslation("profile.company"), VaadinIcon.OFFICE,
                "masterdata.company_name",
                company.isEmpty() ? getTranslation("profile.invoice.placeholder.company") : company);
        Div senderName = createVariableTemplate(getTranslation("profile.invoice.name"), VaadinIcon.USER,
                "masterdata.contact_name",
                fullName.trim().isEmpty() ? getTranslation("profile.invoice.placeholder.name") : fullName.trim());
        Div senderAddress = createVariableTemplate(getTranslation("profile.street"), VaadinIcon.MAP_MARKER,
                "masterdata.street",
                street.trim().isEmpty() ? getTranslation("profile.invoice.placeholder.street") : street.trim());
        Div senderCity = createVariableTemplate(getTranslation("profile.invoice.city"), VaadinIcon.BUILDING,
                "masterdata.city",
                city.trim().isEmpty() ? getTranslation("profile.invoice.placeholder.city") : city.trim());
        Div senderEmail = createVariableTemplate(getTranslation("profile.invoice.email"), VaadinIcon.ENVELOPE,
                "masterdata.email", email.isEmpty() ? getTranslation("profile.invoice.placeholder.email") : email);
        Div senderPhone = createVariableTemplate(getTranslation("profile.invoice.phone"), VaadinIcon.PHONE,
                "masterdata.phone", phone.isEmpty() ? getTranslation("profile.invoice.placeholder.phone") : phone);
        Div invoiceNumber = createVariableTemplate(getTranslation("profile.invoice.element.invoicenumber"),
                VaadinIcon.HASH, "masterdata.invoice_number", "RE-2024-0001");

        // Bereich 2: Leistungen
        Span servicesHeader = new Span(getTranslation("profile.services.label"));
        servicesHeader.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-m)")
                .set("margin-top", "var(--lumo-space-m)");

        // Leistungen als draggable Variable
        Div servicesListBlock = createServicesVariableTemplate(getTranslation("profile.invoice.services.list"),
                VaadinIcon.LIST, "services.list", "Artikel 1: 100,00 €\nArtikel 2: 50,00 €");
        Div servicesNetBlock = createServicesVariableTemplate(getTranslation("profile.invoice.net"),
                VaadinIcon.COIN_PILES, "services.net_total", "150,00 €");
        Div servicesGrossBlock = createServicesVariableTemplate(getTranslation("profile.invoice.gross"),
                VaadinIcon.MONEY, "services.gross_total", "178,50 €");

        // Bereich 3: Kundendaten
        Span customerHeader = new Span(getTranslation("profile.invoice.customerdata"));
        customerHeader.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-m)")
                .set("margin-top", "var(--lumo-space-m)");

        // Kundendaten als Variablen (grün hinterlegt)
        Div customerCompany = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.company"),
                VaadinIcon.OFFICE, "customer.company_name", "Kundenfirma GmbH");
        Div customerName = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.name"),
                VaadinIcon.USER, "customer.contact_name", "Erika Mustermann");
        Div customerAddress = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.street"),
                VaadinIcon.MAP_MARKER, "customer.street", "Kundenstraße 456");
        Div customerCity = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.city"),
                VaadinIcon.BUILDING, "customer.city", "54321 Kundenstadt");
        Div customerEmail = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.email"),
                VaadinIcon.ENVELOPE, "customer.email", "kunde@beispiel.de");
        Div customerPhone = createCustomerVariableTemplate(getTranslation("profile.invoice.customer.phone"),
                VaadinIcon.PHONE, "customer.phone", "0987 654321");

        // Bereich 2: Freie Elemente
        Span freeHeader = new Span(getTranslation("profile.invoice.free.elements"));
        freeHeader.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-m)").set("margin-top",
                "var(--lumo-space-m)");

        // Draggable Templates
        Div textBlock = createDraggableTemplate(getTranslation("profile.invoice.element.text"), VaadinIcon.TEXT_LABEL,
                "text");
        Div headerBlock = createDraggableTemplate(getTranslation("profile.invoice.element.header"), VaadinIcon.HEADER,
                "header");
        Div dateBlock = createDraggableTemplate(getTranslation("profile.invoice.element.date"), VaadinIcon.CALENDAR,
                "date");
        Div customerBlock = createDraggableTemplate(getTranslation("profile.invoice.element.customer"), VaadinIcon.USER,
                "customer");
        Div companyBlock = createDraggableTemplate(getTranslation("profile.invoice.element.company"),
                VaadinIcon.WORKPLACE, "company");
        Div amountBlock = createDraggableTemplate(getTranslation("profile.invoice.element.amount"),
                VaadinIcon.COIN_PILES, "amount");
        Div lineBlock = createDraggableTemplate(getTranslation("profile.invoice.element.line"), VaadinIcon.LINE_V,
                "line");
        Div imageBlock = createDraggableTemplate(getTranslation("profile.invoice.element.image"), VaadinIcon.PICTURE,
                "image");

        panel.add(invoiceHeader, senderCompany, senderName, senderAddress, senderCity, senderEmail, senderPhone,
                invoiceNumber, servicesHeader, servicesListBlock, servicesNetBlock, servicesGrossBlock, customerHeader,
                customerCompany, customerName, customerAddress, customerCity, customerEmail, customerPhone, freeHeader,
                textBlock, headerBlock, dateBlock, customerBlock, companyBlock, amountBlock, lineBlock, imageBlock);

        return panel;
    }

    private Div createVariableTemplate(String label, VaadinIcon icon, String variable, String defaultText) {
        Div template = new Div();
        template.setText(label);
        template.getStyle().set("padding", "var(--lumo-space-s)").set("margin", "var(--lumo-space-xs) 0")
                .set("background-color", "rgba(25, 118, 210, 0.1)").set("border", "1px solid rgba(25, 118, 210, 0.3)")
                .set("border-radius", "var(--lumo-border-radius-m)").set("cursor", "grab").set("display", "flex")
                .set("align-items", "center").set("gap", "var(--lumo-space-s)").set("user-select", "none")
                .set("font-size", "var(--lumo-font-size-s)").set("color", "#1976d2");

        Icon templateIcon = icon.create();
        templateIcon.setSize("var(--lumo-icon-size-s)");
        template.getElement().insertChild(0, templateIcon.getElement());

        template.getElement().setAttribute("draggable", "true");
        template.getElement().setAttribute("data-template-type", "variable");
        template.getElement().setAttribute("data-template-label", label);
        template.getElement().setAttribute("data-variable", variable);
        template.getElement().setAttribute("data-static-text", defaultText);
        template.getElement().setAttribute("data-is-customer", "false");

        template.getElement()
                .executeJs("this.addEventListener('dragstart', function(e) {"
                        + "  e.dataTransfer.setData('template-type', this.getAttribute('data-template-type'));"
                        + "  e.dataTransfer.setData('template-label', this.getAttribute('data-template-label'));"
                        + "  e.dataTransfer.setData('variable', this.getAttribute('data-variable'));"
                        + "  e.dataTransfer.setData('static-text', this.getAttribute('data-static-text'));"
                        + "  e.dataTransfer.setData('is-static', 'true');"
                        + "  e.dataTransfer.setData('is-customer', this.getAttribute('data-is-customer'));"
                        + "  this.style.opacity = '0.5';" + "});" + "this.addEventListener('dragend', function(e) {"
                        + "  this.style.opacity = '1';" + "});");

        return template;
    }

    private Div createCustomerVariableTemplate(String label, VaadinIcon icon, String variable, String defaultText) {
        Div template = new Div();
        template.setText(label);
        template.getStyle().set("padding", "var(--lumo-space-s)").set("margin", "var(--lumo-space-xs) 0")
                .set("background-color", "rgba(46, 204, 113, 0.15)") // Friendly green
                .set("border", "1px solid rgba(46, 204, 113, 0.4)").set("border-radius", "var(--lumo-border-radius-m)")
                .set("cursor", "grab").set("display", "flex").set("align-items", "center")
                .set("gap", "var(--lumo-space-s)").set("user-select", "none")
                .set("font-size", "var(--lumo-font-size-s)").set("color", "#27ae60"); // Dark green text

        Icon templateIcon = icon.create();
        templateIcon.setSize("var(--lumo-icon-size-s)");
        template.getElement().insertChild(0, templateIcon.getElement());

        template.getElement().setAttribute("draggable", "true");
        template.getElement().setAttribute("data-template-type", "variable");
        template.getElement().setAttribute("data-template-label", label);
        template.getElement().setAttribute("data-variable", variable);
        template.getElement().setAttribute("data-static-text", defaultText);
        template.getElement().setAttribute("data-is-customer", "true");

        template.getElement()
                .executeJs("this.addEventListener('dragstart', function(e) {"
                        + "  e.dataTransfer.setData('template-type', this.getAttribute('data-template-type'));"
                        + "  e.dataTransfer.setData('template-label', this.getAttribute('data-template-label'));"
                        + "  e.dataTransfer.setData('variable', this.getAttribute('data-variable'));"
                        + "  e.dataTransfer.setData('static-text', this.getAttribute('data-static-text'));"
                        + "  e.dataTransfer.setData('is-static', 'true');"
                        + "  e.dataTransfer.setData('is-customer', this.getAttribute('data-is-customer'));"
                        + "  this.style.opacity = '0.5';" + "});" + "this.addEventListener('dragend', function(e) {"
                        + "  this.style.opacity = '1';" + "});");

        return template;
    }

    private Div createServicesVariableTemplate(String label, VaadinIcon icon, String variable, String defaultText) {
        Div template = new Div();
        template.setText(label);
        template.getStyle().set("padding", "var(--lumo-space-s)").set("margin", "var(--lumo-space-xs) 0")
                .set("background-color", "rgba(255, 193, 7, 0.15)") // Amber/gelb für Leistungen
                .set("border", "1px solid rgba(255, 193, 7, 0.4)").set("border-radius", "var(--lumo-border-radius-m)")
                .set("cursor", "grab").set("display", "flex").set("align-items", "center")
                .set("gap", "var(--lumo-space-s)").set("user-select", "none")
                .set("font-size", "var(--lumo-font-size-s)").set("color", "#f57c00"); // Dunkles Orange

        Icon templateIcon = icon.create();
        templateIcon.setSize("var(--lumo-icon-size-s)");
        template.getElement().insertChild(0, templateIcon.getElement());

        template.getElement().setAttribute("draggable", "true");
        template.getElement().setAttribute("data-template-type", "variable");
        template.getElement().setAttribute("data-template-label", label);
        template.getElement().setAttribute("data-variable", variable);
        template.getElement().setAttribute("data-static-text", defaultText);
        template.getElement().setAttribute("data-is-customer", "false");
        template.getElement().setAttribute("data-is-services", "true");

        template.getElement()
                .executeJs("this.addEventListener('dragstart', function(e) {"
                        + "  e.dataTransfer.setData('template-type', this.getAttribute('data-template-type'));"
                        + "  e.dataTransfer.setData('template-label', this.getAttribute('data-template-label'));"
                        + "  e.dataTransfer.setData('variable', this.getAttribute('data-variable'));"
                        + "  e.dataTransfer.setData('static-text', this.getAttribute('data-static-text'));"
                        + "  e.dataTransfer.setData('is-static', 'true');"
                        + "  e.dataTransfer.setData('is-customer', this.getAttribute('data-is-customer'));"
                        + "  e.dataTransfer.setData('is-services', this.getAttribute('data-is-services'));"
                        + "  this.style.opacity = '0.5';" + "});" + "this.addEventListener('dragend', function(e) {"
                        + "  this.style.opacity = '1';" + "});");

        return template;
    }

    private Div createDraggableTemplate(String label, VaadinIcon icon, String type) {
        Div template = new Div();
        template.setText(label);
        template.getStyle().set("padding", "var(--lumo-space-s)").set("margin", "var(--lumo-space-xs) 0")
                .set("background-color", "var(--lumo-base-color)").set("border", "1px solid var(--lumo-contrast-20pct)")
                .set("border-radius", "var(--lumo-border-radius-m)").set("cursor", "grab").set("display", "flex")
                .set("align-items", "center").set("gap", "var(--lumo-space-s)").set("user-select", "none");

        Icon templateIcon = icon.create();
        templateIcon.setSize("var(--lumo-icon-size-s)");
        template.getElement().insertChild(0, templateIcon.getElement());

        template.getElement().setAttribute("draggable", "true");
        template.getElement().setAttribute("data-template-type", type);
        template.getElement().setAttribute("data-template-label", label);

        template.getElement()
                .executeJs("this.addEventListener('dragstart', function(e) {"
                        + "  e.dataTransfer.setData('template-type', this.getAttribute('data-template-type'));"
                        + "  e.dataTransfer.setData('template-label', this.getAttribute('data-template-label'));"
                        + "  e.dataTransfer.setData('is-static', 'false');" + "  this.style.opacity = '0.5';" + "});"
                        + "this.addEventListener('dragend', function(e) {" + "  this.style.opacity = '1';" + "});");

        return template;
    }

    private VerticalLayout createPropertiesPanelForProfile() {
        VerticalLayout panel = new VerticalLayout();
        panel.setPadding(false);
        panel.setSpacing(true);
        panel.setHeightFull();

        Span header = new Span(getTranslation("profile.invoice.properties"));
        header.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-l)");

        Div infoText = new Div();
        infoText.setText(getTranslation("profile.invoice.properties.info"));
        infoText.getStyle().set("color", "var(--lumo-secondary-text-color)").set("font-size",
                "var(--lumo-font-size-s)");

        panel.add(header, infoText);

        return panel;
    }

    @ClientCallable
    public void updatePropertiesPanel(String elementId, String elementType, String text, Double x, Double y,
            Integer fontSize, String color, Double width, Double height, Boolean isStatic, String variable) {
        getUI().ifPresent(ui -> ui.access(() -> {
            propertiesPanelProfile.removeAll();

            Span header = new Span(getTranslation("profile.invoice.properties"));
            header.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-l)");

            // Element Typ Anzeige
            String typeDisplay = getTranslation("profile.invoice.type") + ": " + elementType;
            if (variable != null && !variable.isEmpty()) {
                typeDisplay += " (" + getTranslation("profile.invoice.variable") + ")";
            } else if (Boolean.TRUE.equals(isStatic)) {
                typeDisplay += " (" + getTranslation("profile.basicdata") + ")";
            }
            Span typeLabel = new Span(typeDisplay);
            typeLabel.getStyle().set("font-size", "var(--lumo-font-size-s)");

            propertiesPanelProfile.add(header, typeLabel);

            // Variable anzeigen wenn vorhanden
            if (variable != null && !variable.isEmpty()) {
                TextField variableField = new TextField(getTranslation("profile.invoice.variable"));
                variableField.setValue(variable);
                variableField.setReadOnly(true);
                variableField.setWidthFull();

                // Beschreibung basierend auf der Variable
                String description = getVariableDescription(variable);
                variableField.setHelperText(description);

                propertiesPanelProfile.add(variableField);
            }

            // Für Bildelemente: Upload-Button anzeigen
            if ("image".equals(elementType)) {
                MemoryBuffer buffer = new MemoryBuffer();
                Upload upload = new Upload(buffer);
                upload.setAcceptedFileTypes("image/png", "image/jpeg", "image/jpg", "image/gif", "image/webp");
                upload.setMaxFileSize(5 * 1024 * 1024); // 5 MB
                upload.setDropLabel(new Span(getTranslation("profile.invoice.image.drop")));
                upload.setWidthFull();

                upload.addSucceededListener(event -> {
                    try {
                        // Bild als Base64 kodieren
                        byte[] bytes = buffer.getInputStream().readAllBytes();
                        String base64 = java.util.Base64.getEncoder().encodeToString(bytes);
                        String mimeType = event.getMIMEType();
                        String dataUrl = "data:" + mimeType + ";base64," + base64;

                        // An JavaScript übergeben
                        getElement()
                                .executeJs("if (window.updateProfileElementImage) { window.updateProfileElementImage('"
                                        + elementId + "', $0); }", dataUrl);
                        Notification.show(getTranslation("profile.invoice.image.uploaded"), 3000,
                                Notification.Position.BOTTOM_CENTER);
                    } catch (Exception ex) {
                        Notification.show(getTranslation("profile.invoice.image.upload.error", ex.getMessage()), 3000,
                                Notification.Position.BOTTOM_CENTER);
                    }
                });

                upload.addFileRejectedListener(event -> {
                    Notification.show(getTranslation("profile.invoice.file.rejected", event.getErrorMessage()), 3000,
                            Notification.Position.BOTTOM_CENTER);
                });

                propertiesPanelProfile.add(upload);
            }

            // Text Feld (nur für Text-Elemente)
            if (!"line".equals(elementType) && !"image".equals(elementType)) {
                TextField textField = new TextField(getTranslation("profile.invoice.element.text"));
                textField.setValue(text != null ? text : "");
                textField.setWidthFull();
                // Statische Elemente können nicht editiert werden
                if (Boolean.TRUE.equals(isStatic)) {
                    textField.setReadOnly(true);
                    textField.setHelperText(getTranslation("profile.invoice.text.from.masterdata"));
                } else {
                    textField.addValueChangeListener(e -> {
                        getElement()
                                .executeJs("if (window.updateProfileElementText) { window.updateProfileElementText('"
                                        + elementId + "', $0); }", e.getValue());
                    });
                }
                propertiesPanelProfile.add(textField);
            }

            // X Position
            TextField xField = new TextField(getTranslation("profile.invoice.xposition"));
            xField.setValue(x != null ? String.valueOf(Math.round(x)) : "0");
            xField.setWidthFull();
            xField.addValueChangeListener(e -> {
                try {
                    double newX = Double.parseDouble(e.getValue());
                    getElement().executeJs(
                            "if (window.updateProfileElementPosition) { window.updateProfileElementPosition('"
                                    + elementId + "', $0, null); }",
                            newX);
                } catch (NumberFormatException ignored) {
                }
            });
            propertiesPanelProfile.add(xField);

            // Y Position
            TextField yField = new TextField(getTranslation("profile.invoice.yposition"));
            yField.setValue(y != null ? String.valueOf(Math.round(y)) : "0");
            yField.setWidthFull();
            yField.addValueChangeListener(e -> {
                try {
                    double newY = Double.parseDouble(e.getValue());
                    getElement().executeJs(
                            "if (window.updateProfileElementPosition) { window.updateProfileElementPosition('"
                                    + elementId + "', null, $0); }",
                            newY);
                } catch (NumberFormatException ignored) {
                }
            });
            propertiesPanelProfile.add(yField);

            // Font Size (nur für Text-Elemente)
            if (!"line".equals(elementType) && !"image".equals(elementType)) {
                TextField fontSizeField = new TextField(getTranslation("profile.invoice.fontsize"));
                fontSizeField.setValue(fontSize != null ? String.valueOf(fontSize) : "16");
                fontSizeField.setWidthFull();
                fontSizeField.addValueChangeListener(e -> {
                    try {
                        int newSize = Integer.parseInt(e.getValue());
                        getElement().executeJs(
                                "if (window.updateProfileElementFontSize) { window.updateProfileElementFontSize('"
                                        + elementId + "', $0); }",
                                newSize);
                    } catch (NumberFormatException ignored) {
                    }
                });
                propertiesPanelProfile.add(fontSizeField);

                // Farbe
                Div colorContainer = new Div();
                colorContainer.getStyle().set("display", "flex").set("align-items", "center")
                        .set("gap", "var(--lumo-space-s)").set("margin-top", "var(--lumo-space-s)");

                Span colorLabel = new Span(getTranslation("profile.invoice.color"));
                colorLabel.getStyle().set("font-size", "var(--lumo-font-size-s)");

                Input colorPicker = new Input();
                colorPicker.setType("color");
                colorPicker.setValue(color != null ? color : "#333333");
                colorPicker.getStyle().set("width", "50px").set("height", "32px").set("padding", "0")
                        .set("border", "1px solid var(--lumo-contrast-20pct)")
                        .set("border-radius", "var(--lumo-border-radius-m)").set("cursor", "pointer");

                TextField colorHexField = new TextField();
                colorHexField.setValue(color != null ? color : "#333333");
                colorHexField.setWidth("100px");
                colorHexField.getStyle().set("margin", "0");

                colorPicker.addValueChangeListener(e -> {
                    String newColor = e.getValue();
                    colorHexField.setValue(newColor);
                    getElement().executeJs("if (window.updateProfileElementColor) { window.updateProfileElementColor('"
                            + elementId + "', $0); }", newColor);
                });

                colorHexField.addValueChangeListener(e -> {
                    String newColor = e.getValue();
                    if (newColor.matches("^#[0-9A-Fa-f]{6}$")) {
                        colorPicker.setValue(newColor);
                        getElement()
                                .executeJs("if (window.updateProfileElementColor) { window.updateProfileElementColor('"
                                        + elementId + "', $0); }", newColor);
                    }
                });

                colorContainer.add(colorLabel, colorPicker, colorHexField);
                propertiesPanelProfile.add(colorContainer);
            }

            // Löschen Button
            Button deleteButton = new Button(getTranslation("profile.invoice.element.delete"),
                    new Icon(VaadinIcon.TRASH));
            deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
            deleteButton.setWidthFull();
            deleteButton.addClickListener(e -> {
                getElement().executeJs(
                        "if (window.deleteProfileElement) { window.deleteProfileElement('" + elementId + "'); }");
                resetPropertiesPanel();
            });
            propertiesPanelProfile.add(deleteButton);
        }));
    }

    @ClientCallable
    public void resetPropertiesPanel() {
        getUI().ifPresent(ui -> ui.access(() -> {
            if (propertiesPanelProfile == null)
                return;

            propertiesPanelProfile.removeAll();

            Span header = new Span(getTranslation("profile.invoice.properties"));
            header.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-l)");

            Div infoText = new Div();
            infoText.setText(getTranslation("profile.invoice.properties.info"));
            infoText.getStyle().set("color", "var(--lumo-secondary-text-color)").set("font-size",
                    "var(--lumo-font-size-s)");

            propertiesPanelProfile.add(header, infoText);
        }));
    }

    /**
     * Called by JavaScript when the canvas is ready
     */
    @ClientCallable
    public void onCanvasReady() {
        System.out.println("Canvas ready, loading template...");
        loadInvoiceTemplate();
    }

    /**
     * Load the saved invoice template from database and display it on the canvas
     */
    private void loadInvoiceTemplate() {
        try {
            java.util.Optional<de.assecutor.votianlt.model.InvoiceTemplate> optionalTemplate = invoiceTemplateService
                    .getTemplateByUserId(currentUser.getId().toString());
            if (optionalTemplate.isPresent()) {
                String templateData = optionalTemplate.get().getTemplateData();
                if (templateData != null && !templateData.isEmpty()) {
                    System.out.println("Loading template data: "
                            + templateData.substring(0, Math.min(100, templateData.length())) + "...");
                    // Escape the JSON string for JavaScript
                    String escapedJson = templateData.replace("\\", "\\\\").replace("'", "\\'").replace("\n", "\\n")
                            .replace("\r", "\\r");
                    // Build masterdata values JSON
                    String company = safe(currentUser.getCompany());
                    String fullName = safe(currentUser.getFirstname()) + " " + safe(currentUser.getName());
                    String street = safe(currentUser.getStreet()) + " " + safe(currentUser.getHouseNumber());
                    String city = safe(currentUser.getZip()) + " " + safe(currentUser.getCity());
                    String email = safe(currentUser.getEmail());
                    String phone = safe(currentUser.getPhone());
                    String prefix = prefixField.getValue();
                    String invoiceNumber = (prefix != null && !prefix.isBlank() ? prefix : "") + "12345";
                    String masterdataJson = "{" + "'masterdata.company_name': '" + company.replace("'", "\\'") + "',"
                            + "'masterdata.contact_name': '" + fullName.replace("'", "\\'") + "',"
                            + "'masterdata.street': '" + street.replace("'", "\\'") + "'," + "'masterdata.city': '"
                            + city.replace("'", "\\'") + "'," + "'masterdata.email': '" + email.replace("'", "\\'")
                            + "'," + "'masterdata.phone': '" + phone.replace("'", "\\'") + "',"
                            + "'masterdata.invoice_number': '" + invoiceNumber.replace("'", "\\'") + "'" + "}";
                    BigDecimal rate = currentUser.getVatRate() != null ? currentUser.getVatRate()
                            : Service.FIXED_VAT_RATE;
                    double vatRateJs = rate.doubleValue();
                    getElement().executeJs("setTimeout(function() { "
                            + "  if (window.loadProfileTemplate && document.getElementById('invoice-canvas-container-profile')) { "
                            + "    console.log('Loading template into canvas...'); "
                            + "    window.profileInvoiceServiceData = null; "
                            + "    window.profileInvoiceVatRate = " + vatRateJs + "; "
                            + "    window.masterdataValues = "
                            + masterdataJson + "; " + "    var templateData = JSON.parse('" + escapedJson + "'); "
                            + "    window.loadProfileTemplate(templateData); " + "  } else { "
                            + "    console.error('loadProfileTemplate or canvas not available'); " + "  } "
                            + "}, 300);");
                }
            } else {
                System.out.println("No template found for user: " + currentUser.getId());
            }
        } catch (Exception ex) {
            System.err.println("Fehler beim Laden des Templates: " + ex.getMessage());
            ex.printStackTrace();
        }
    }

    /**
     * Get a human-readable description for a variable
     */
    private String getVariableDescription(String variable) {
        return switch (variable) {
        case "masterdata.company_name" -> "Name Ihrer Firma";
        case "masterdata.contact_name" -> "Name des Ansprechpartners";
        case "masterdata.street" -> "Straße und Hausnummer";
        case "masterdata.city" -> "PLZ und Ort";
        case "masterdata.email" -> "E-Mail-Adresse";
        case "masterdata.phone" -> "Telefonnummer";
        case "customer.company_name" -> "Firmenname des Kunden";
        case "customer.contact_name" -> "Name des Kundenansprechpartners";
        case "customer.street" -> "Straße des Kunden";
        case "customer.city" -> "PLZ und Ort des Kunden";
        case "customer.email" -> "E-Mail des Kunden";
        case "customer.phone" -> "Telefon des Kunden";
        case "services.list" -> "Liste aller Leistungen auf der Rechnung";
        case "services.net_total" -> "Nettosumme aller Leistungen";
        case "services.gross_total" -> "Bruttosumme aller Leistungen";
        default -> "Variable: " + variable;
        };
    }

    /**
     * Create the Leistungskatalog tab with services grid and management
     * functionality
     */
    private VerticalLayout createServicesTab() {
        VerticalLayout servicesTab = new VerticalLayout();
        servicesTab.setWidthFull();
        servicesTab.setHeightFull();
        servicesTab.setPadding(false);
        servicesTab.setSpacing(true);

        // Header
        Span header = new Span(getTranslation("profile.services"));
        header.getStyle().set("font-weight", "bold").set("font-size", "var(--lumo-font-size-l)").set("margin-bottom",
                "var(--lumo-space-m)");

        // Description
        Span description = new Span(getTranslation("profile.services.description"));
        description.getStyle().set("color", "var(--lumo-secondary-text-color)").set("font-size",
                "var(--lumo-font-size-s)");

        servicesTab.add(header, description);

        // Grid for displaying services
        servicesGrid = new Grid<>();
        servicesGrid.setWidthFull();
        servicesGrid.setHeight("300px");

        // Configure grid columns
        servicesGrid.addColumn(Service::getName).setHeader(getTranslation("common.name")).setSortable(true);
        servicesGrid.addColumn(service -> {
            if (service.getCalculationBasis() != null) {
                return switch (service.getCalculationBasis()) {
                case DISTANCE -> getTranslation("profile.services.basis.distance");
                case TIME -> getTranslation("profile.services.basis.time");
                case FLAT_RATE -> getTranslation("profile.services.basis.flatrate");
                };
            }
            return "";
        }).setHeader(getTranslation("profile.services.basis")).setSortable(true);

        servicesGrid.addColumn(service -> {
            if (service.getCalculationBasis() == Service.CalculationBasis.FLAT_RATE && service.getPrice() != null) {
                return service.getPrice().setScale(2, RoundingMode.HALF_UP) + " €";
            }
            return getTranslation("profile.services.calculated");
        }).setHeader(getTranslation("common.price")).setSortable(true);

        servicesGrid
                .addColumn(
                        service -> service.isMandatory() ? getTranslation("common.yes") : getTranslation("common.no"))
                .setHeader(getTranslation("profile.services.mandatory")).setSortable(true);

        // Actions column with edit and delete buttons
        servicesGrid.addComponentColumn(service -> {
            HorizontalLayout actionsLayout = new HorizontalLayout();
            actionsLayout.setSpacing(false);
            actionsLayout.setPadding(false);
            actionsLayout.setAlignItems(FlexComponent.Alignment.CENTER);

            Button editButton = new Button(new Icon(VaadinIcon.EDIT));
            editButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY, ButtonVariant.LUMO_SMALL);
            editButton.addClickListener(e -> openServiceDialog(service));

            Button deleteButton = new Button(new Icon(VaadinIcon.TRASH));
            deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY,
                    ButtonVariant.LUMO_SMALL);
            deleteButton.addClickListener(e -> deleteService(service));

            actionsLayout.add(editButton, deleteButton);
            return actionsLayout;
        }).setHeader(getTranslation("common.actions")).setFlexGrow(0).setWidth("120px");

        servicesTab.add(servicesGrid);

        // Add service button
        Button addServiceButton = new Button(getTranslation("profile.services.add"), new Icon(VaadinIcon.PLUS));
        addServiceButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        addServiceButton.addClickListener(e -> openServiceDialog(null));

        servicesTab.add(addServiceButton);

        // Load services for current user
        loadServices(servicesGrid);

        return servicesTab;
    }

    /**
     * Load services for the current user and populate the grid
     */
    private void loadServices(Grid<Service> servicesGrid) {
        try {
            List<Service> userServices = serviceRepository.findByUserId(currentUser.getId().toString());
            servicesGrid.setItems(userServices);
        } catch (Exception e) {
            Notification.show(getTranslation("profile.services.load.error", e.getMessage()), 3000,
                    Notification.Position.BOTTOM_CENTER);
        }
    }

    /**
     * Open dialog for adding/editing a service
     */
    private void openServiceDialog(Service service) {
        Dialog dialog = DialogStylingHelper.createStyledDialog(
                service == null ? getTranslation("profile.services.dialog.create")
                        : getTranslation("profile.services.dialog.edit"),
                "560px");
        dialog.setCloseOnOutsideClick(false);

        // Form layout
        VerticalLayout formLayout = DialogStylingHelper.createContentLayout("420px");

        // Name field
        TextField nameField = new TextField(getTranslation("common.name"));
        nameField.setWidthFull();
        nameField.setRequired(true);
        nameField.setRequiredIndicatorVisible(true);

        // Calculation basis combo box
        ComboBox<Service.CalculationBasis> calculationBasisCombo = new ComboBox<>(
                getTranslation("profile.services.basis"));
        calculationBasisCombo.setWidthFull();
        calculationBasisCombo.setItems(Service.CalculationBasis.values());
        calculationBasisCombo.setItemLabelGenerator(basis -> {
            return switch (basis) {
            case DISTANCE -> getTranslation("profile.services.basis.distance");
            case TIME -> getTranslation("profile.services.basis.time");
            case FLAT_RATE -> getTranslation("profile.services.basis.flatrate");
            };
        });
        calculationBasisCombo.setRequired(true);
        calculationBasisCombo.setRequiredIndicatorVisible(true);

        // Mandatory checkbox
        Checkbox mandatoryCheckbox = new Checkbox(getTranslation("profile.services.mandatory"));
        mandatoryCheckbox.setValue(false);

        // Set values if editing existing service
        if (service != null) {
            nameField.setValue(service.getName());
            calculationBasisCombo.setValue(service.getCalculationBasis());
            mandatoryCheckbox.setValue(service.isMandatory());
        }

        // Price fields for different calculation bases
        NumberField flatRatePriceField = new NumberField(getTranslation("profile.services.price.flatrate"));
        flatRatePriceField.setWidthFull();
        flatRatePriceField.setMin(0);
        flatRatePriceField.setStep(0.01);
        flatRatePriceField.setValue(0.0); // Default 0.00
        flatRatePriceField.setRequired(true);
        flatRatePriceField.setRequiredIndicatorVisible(true);

        NumberField distancePriceField = new NumberField(getTranslation("profile.services.price.distance"));
        distancePriceField.setWidthFull();
        distancePriceField.setMin(0);
        distancePriceField.setStep(0.01);
        distancePriceField.setValue(0.0); // Default 0.00
        distancePriceField.setRequired(true);
        distancePriceField.setRequiredIndicatorVisible(true);

        NumberField timePriceField = new NumberField(getTranslation("profile.services.price.time"));
        timePriceField.setWidthFull();
        timePriceField.setMin(0);
        timePriceField.setStep(0.01);
        timePriceField.setValue(0.0); // Default 0.00
        timePriceField.setRequired(true);
        timePriceField.setRequiredIndicatorVisible(true);

        // Set values if editing existing service
        if (service != null) {
            nameField.setValue(service.getName());
            calculationBasisCombo.setValue(service.getCalculationBasis());

            // Set the appropriate price field based on calculation basis
            if (service.getCalculationBasis() != null) {
                switch (service.getCalculationBasis()) {
                case DISTANCE:
                    if (service.getPricePerKilometer() != null) {
                        distancePriceField.setValue(service.getPricePerKilometer().doubleValue());
                    }
                    break;
                case TIME:
                    if (service.getPricePer15Minutes() != null) {
                        timePriceField.setValue(service.getPricePer15Minutes().doubleValue());
                    }
                    break;
                case FLAT_RATE:
                    if (service.getPrice() != null) {
                        flatRatePriceField.setValue(service.getPrice().doubleValue());
                    }
                    break;
                }
            }
        }

        // Add value change listener to show/hide appropriate price field based on
        // calculation basis
        calculationBasisCombo.addValueChangeListener(e -> {
            Service.CalculationBasis selectedBasis = e.getValue();
            flatRatePriceField.setVisible(selectedBasis == Service.CalculationBasis.FLAT_RATE);
            distancePriceField.setVisible(selectedBasis == Service.CalculationBasis.DISTANCE);
            timePriceField.setVisible(selectedBasis == Service.CalculationBasis.TIME);
        });

        // Initialize price field visibility based on current selection
        Service.CalculationBasis initialBasis = calculationBasisCombo.getValue();
        flatRatePriceField.setVisible(initialBasis == Service.CalculationBasis.FLAT_RATE);
        distancePriceField.setVisible(initialBasis == Service.CalculationBasis.DISTANCE);
        timePriceField.setVisible(initialBasis == Service.CalculationBasis.TIME);

        formLayout.add(nameField, calculationBasisCombo, flatRatePriceField, distancePriceField, timePriceField,
                mandatoryCheckbox);

        // Action buttons
        Button cancelButton = new Button(getTranslation("button.cancel"), e -> dialog.close());
        cancelButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);

        Button saveButton = new Button(getTranslation("button.savechanges"), e -> {
            if (validateServiceForm(nameField, calculationBasisCombo, flatRatePriceField, distancePriceField,
                    timePriceField, mandatoryCheckbox)) {
                // Get the appropriate price based on calculation basis
                BigDecimal priceValue = BigDecimal.ZERO;
                Service.CalculationBasis selectedBasis = calculationBasisCombo.getValue();

                if (selectedBasis == Service.CalculationBasis.FLAT_RATE && flatRatePriceField.getValue() != null) {
                    priceValue = new BigDecimal(flatRatePriceField.getValue());
                } else if (selectedBasis == Service.CalculationBasis.DISTANCE
                        && distancePriceField.getValue() != null) {
                    priceValue = new BigDecimal(distancePriceField.getValue());
                } else if (selectedBasis == Service.CalculationBasis.TIME && timePriceField.getValue() != null) {
                    priceValue = new BigDecimal(timePriceField.getValue());
                }

                boolean mandatory = mandatoryCheckbox.getValue();
                saveService(service, nameField.getValue(), calculationBasisCombo.getValue(), priceValue, mandatory);
                dialog.close();
            }
        });
        saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        dialog.add(DialogStylingHelper.wrapContent(formLayout));
        dialog.getFooter().add(cancelButton, saveButton);
        dialog.open();
    }

    /**
     * Validate service form fields
     */
    private boolean validateServiceForm(TextField nameField, ComboBox<Service.CalculationBasis> calculationBasisCombo,
            NumberField flatRatePriceField, NumberField distancePriceField, NumberField timePriceField,
            Checkbox mandatoryCheckbox) {
        boolean isValid = true;

        if (nameField.isEmpty()) {
            nameField.setInvalid(true);
            nameField.setErrorMessage(getTranslation("profile.services.validation.name"));
            isValid = false;
        } else {
            nameField.setInvalid(false);
        }

        if (calculationBasisCombo.isEmpty()) {
            calculationBasisCombo.setInvalid(true);
            calculationBasisCombo.setErrorMessage(getTranslation("profile.services.validation.basis"));
            isValid = false;
        } else {
            calculationBasisCombo.setInvalid(false);
        }

        // Validate the appropriate price field based on calculation basis
        Service.CalculationBasis selectedBasis = calculationBasisCombo.getValue();
        if (selectedBasis == Service.CalculationBasis.FLAT_RATE && flatRatePriceField.isVisible()) {
            if (flatRatePriceField.isEmpty() || flatRatePriceField.getValue() == null) {
                flatRatePriceField.setInvalid(true);
                flatRatePriceField.setErrorMessage(getTranslation("profile.services.validation.flatrate"));
                isValid = false;
            } else {
                flatRatePriceField.setInvalid(false);
            }
        } else if (selectedBasis == Service.CalculationBasis.DISTANCE && distancePriceField.isVisible()) {
            if (distancePriceField.isEmpty() || distancePriceField.getValue() == null) {
                distancePriceField.setInvalid(true);
                distancePriceField.setErrorMessage(getTranslation("profile.services.validation.distance"));
                isValid = false;
            } else {
                distancePriceField.setInvalid(false);
            }
        } else if (selectedBasis == Service.CalculationBasis.TIME && timePriceField.isVisible()) {
            if (timePriceField.isEmpty() || timePriceField.getValue() == null) {
                timePriceField.setInvalid(true);
                timePriceField.setErrorMessage(getTranslation("profile.services.validation.time"));
                isValid = false;
            } else {
                timePriceField.setInvalid(false);
            }
        }

        return isValid;
    }

    /**
     * Save service to database
     */
    private void saveService(Service existingService, String name, Service.CalculationBasis calculationBasis,
            BigDecimal priceValue, boolean mandatory) {
        try {
            Service service;
            if (existingService != null) {
                service = existingService;
                service.setName(name);
                service.setCalculationBasis(calculationBasis);
                service.setVatRate(Service.FIXED_VAT_RATE);
                service.setMandatory(mandatory);

                // Set the appropriate price field based on calculation basis
                switch (calculationBasis) {
                case DISTANCE:
                    service.setPricePerKilometer(priceValue);
                    service.setPrice(null);
                    service.setPricePer15Minutes(null);
                    break;
                case TIME:
                    service.setPricePer15Minutes(priceValue);
                    service.setPrice(null);
                    service.setPricePerKilometer(null);
                    break;
                case FLAT_RATE:
                    service.setPrice(priceValue);
                    service.setPricePerKilometer(null);
                    service.setPricePer15Minutes(null);
                    break;
                }
            } else {
                service = new Service(currentUser.getId().toString(), name, calculationBasis, priceValue,
                        Service.FIXED_VAT_RATE, mandatory);
            }

            serviceRepository.save(service);
            Notification.show(getTranslation("profile.services.saved"), 3000, Notification.Position.BOTTOM_CENTER);

            // Refresh the grid by reloading services
            if (servicesGrid != null) {
                loadServices(servicesGrid);
            }

        } catch (Exception e) {
            Notification.show(getTranslation("profile.services.save.error", e.getMessage()), 5000,
                    Notification.Position.BOTTOM_CENTER);
        }
    }

    /**
     * Delete a service
     */
    private void deleteService(Service service) {
        try {
            serviceRepository.delete(service);
            Notification.show(getTranslation("profile.services.deleted"), 3000, Notification.Position.BOTTOM_CENTER);

            // Refresh the grid by reloading services
            if (servicesGrid != null) {
                loadServices(servicesGrid);
            }

        } catch (Exception e) {
            Notification.show(getTranslation("profile.services.delete.error", e.getMessage()), 5000,
                    Notification.Position.BOTTOM_CENTER);
        }
    }

    /**
     * Sets the language cookie via JavaScript so the selected language is available
     * even before the user logs in (e.g., on the login page).
     * 
     * @param language
     *            the selected language
     */
    private void setLanguageCookie(Language language) {
        String languageCode = switch (language) {
        case DE -> "DE";
        case EN -> "EN";
        case FR -> "FR";
        case ES -> "ES";
        case TR -> "TR";
        case PL -> "PL";
        case RU -> "RU";
        case EE -> "EE";
        case LV -> "LV";
        case LT -> "LT";
        };

        // Execute JavaScript to set the cookie
        UI.getCurrent().getPage().executeJs("const maxAge = 365 * 24 * 60 * 60;"
                + "document.cookie = 'votianlt.language=' + $0 + ';path=/;max-age=' + maxAge + ';SameSite=Lax';",
                languageCode);
    }

    @Override
    public String getPageTitle() {
        return getTranslation("page.title.profile.edit");
    }
}
