package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.combobox.ComboBox;

import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.html.Span;
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.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.NumberField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Menu;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.tabs.TabSheet;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility;
import de.assecutor.votianlt.model.Job;
import de.assecutor.votianlt.model.task.BaseTask;
import de.assecutor.votianlt.model.task.TaskType;
import de.assecutor.votianlt.model.task.ConfirmationTask;
import de.assecutor.votianlt.model.task.SignatureTask;
import de.assecutor.votianlt.model.task.TodoListTask;
import de.assecutor.votianlt.model.task.PhotoTask;
import de.assecutor.votianlt.model.task.BarcodeTask;
import de.assecutor.votianlt.model.task.CommentTask;
import de.assecutor.votianlt.pages.service.AddJobService;
import de.assecutor.votianlt.pages.service.CustomerService;
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;
import de.assecutor.votianlt.pages.service.AddCustomerService;
import de.assecutor.votianlt.model.Customer;
import de.assecutor.votianlt.pages.service.AppUserService;
import de.assecutor.votianlt.model.AppUser;

import jakarta.annotation.security.RolesAllowed;
import lombok.extern.slf4j.Slf4j;
import de.assecutor.votianlt.model.CargoItem;
import java.util.*;
import java.util.Objects;
import java.util.Optional;

@Route(value = "add_job", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@PageTitle("Neuen Auftrag anlegen")
@Menu(order = 0, icon = "vaadin:clipboard-check", title = "Auftragserstellung")
@RolesAllowed("USER")
@Slf4j
public class AddJobView extends Main {

    private final AddJobService addJobService;
    private final CustomerService customerService;
    private final AddCustomerService addCustomerService;
    private final AppUserService appUserService;

    // Customer selection
    private ComboBox<String> customerSelection;
    private Button preloadAddressButton;

    // Pickup address fields
    private ComboBox<String> pickupCompany;
    private ComboBox<String> pickupSalutation;
    private TextField pickupFirstName;
    private TextField pickupLastName;
    private TextField pickupPhone;
    private TextField pickupStreet;
    private TextField pickupHouseNumber;
    private TextField pickupAddressAddition;
    private TextField pickupZip;
    private TextField pickupCity;
    private Checkbox savePickupAddress;

    // Delivery address fields
    private ComboBox<String> deliveryCompany;
    private ComboBox<String> deliverySalutation;
    private TextField deliveryFirstName;
    private TextField deliveryLastName;
    private TextField deliveryPhone;
    private TextField deliveryStreet;
    private TextField deliveryHouseNumber;
    private TextField deliveryAddressAddition;
    private TextField deliveryZip;
    private TextField deliveryCity;
    private Checkbox saveDeliveryAddress;

    // Digital processing
    private Checkbox digitalProcessing;
    private ComboBox<AppUser> appUser;

    // Price field
    private TextField price;

    // Date picker fields for appointments
    private DatePicker pickupDate;
    private DatePicker deliveryDate;

    private com.vaadin.flow.component.tabs.Tab addressesTab;
    private com.vaadin.flow.component.tabs.Tab appointmentsTab;
    private com.vaadin.flow.component.tabs.Tab cargoTab;
    private com.vaadin.flow.component.tabs.Tab tasksTab;
    private com.vaadin.flow.component.tabs.Tab priceTab;

    // Submit button
    private Button submitButton;

    // Backing list for cargo items to mirror UI rows
    private final List<CargoItem> cargoItemsState = new ArrayList<>();
    // Stage sections for drag and drop
    // Backing list for tasks to mirror UI rows
    private final List<BaseTask> tasksState = new ArrayList<>();
    // Dynamic lists and additional controls
    // Cargo section UI refs for error highlighting
    private VerticalLayout cargoAreaContainer;
    private Span cargoError;
    private VerticalLayout cargoList;
    private VerticalLayout tasksList;
    private TextArea remarkArea;
    private VerticalLayout pickupSection;
    private VerticalLayout deliverySection;

    private final Binder<Job> binder = new Binder<>(Job.class);

    // Mapping für die Anzeige-Labels der Kunden zur Entität
    private final Map<String, Customer> customerLabelToEntity = new LinkedHashMap<>();

    // Available app users for the current user
    private List<AppUser> availableAppUsers;

    public AddJobView(AddJobService addJobService, AddCustomerService addCustomerService,
            CustomerService customerService, AppUserService appUserService) {
        this.addJobService = addJobService;
        this.addCustomerService = addCustomerService;
        this.customerService = customerService;
        this.appUserService = appUserService;
        initializeComponents();
        setupLayout();
        setupValidation();
        loadDraftIfExists();
    }

    private void initializeComponents() {
        // Customer selection
        customerSelection = new ComboBox<>("Auftraggeber/Rechnungsempfänger");
        customerSelection.setPlaceholder("Wählen Sie einen Auftraggeber aus...");
        customerSelection.setWidthFull();
        customerSelection.setRequiredIndicatorVisible(true);
        // Mit Kunden des angemeldeten Benutzers befüllen und Mapping aufbauen
        List<Customer> ownerCustomers = customerService.findAllForCurrentOwner();
        customerLabelToEntity.clear();
        for (Customer c : ownerCustomers) {
            String label = (c.getCompanyName() != null && !c.getCompanyName().isBlank())
                    ? c.getCompanyName() + " | "
                            + ((c.getFirstname() != null ? c.getFirstname() : "") + " "
                                    + (c.getLastName() != null ? c.getLastName() : "")).trim()
                    : ((c.getFirstname() != null ? c.getFirstname() : "") + " "
                            + (c.getLastName() != null ? c.getLastName() : "")).trim();
            if (label.isBlank()) {
                label = "Unbenannter Kunde";
            }
            // Bei Duplikaten Label einzigartig machen
            String uniqueLabel = label;
            int counter = 2;
            while (customerLabelToEntity.containsKey(uniqueLabel)) {
                uniqueLabel = label + " (" + counter++ + ")";
            }
            customerLabelToEntity.put(uniqueLabel, c);
        }
        customerSelection.setItems(new ArrayList<>(customerLabelToEntity.keySet()));

        // Bei Auswahl eines Kunden Abholfelder befüllen
        customerSelection.addValueChangeListener(ev -> {
            String selected = ev.getValue();
            if (selected == null) {
                // Wenn kein Kunde ausgewählt ist, Checkbox wieder aktivieren
                savePickupAddress.setValue(true);
                return;
            }
            Customer c = customerLabelToEntity.get(selected);
            if (c == null)
                return;

            // Pickup-Checkbox deaktivieren, da Kunde bereits existiert
            savePickupAddress.setValue(false);

            // Firma
            if (c.getCompanyName() != null) {
                pickupCompany.setValue(c.getCompanyName());
            } else {
                pickupCompany.clear();
            }
            // Anrede (nur setzen, wenn vorhanden und zulässig)
            if (c.getTitle() != null && ("Herr".equalsIgnoreCase(c.getTitle()) || "Frau".equalsIgnoreCase(c.getTitle())
                    || "Divers".equalsIgnoreCase(c.getTitle()))) {
                pickupSalutation.setValue(c.getTitle());
            } else {
                pickupSalutation.clear();
            }
            // Namen
            if (c.getFirstname() != null) {
                pickupFirstName.setValue(c.getFirstname());
            } else {
                pickupFirstName.clear();
            }
            if (c.getLastName() != null) {
                pickupLastName.setValue(c.getLastName());
            } else {
                pickupLastName.clear();
            }
            // Telefon
            if (c.getTelephone() != null) {
                pickupPhone.setValue(c.getTelephone());
            } else {
                pickupPhone.clear();
            }
            // Adresse
            if (c.getStreet() != null) {
                pickupStreet.setValue(c.getStreet());
            } else {
                pickupStreet.clear();
            }
            if (c.getHouseNumber() != null) {
                pickupHouseNumber.setValue(c.getHouseNumber());
            } else {
                pickupHouseNumber.clear();
            }
            if (c.getAddressAddition() != null) {
                pickupAddressAddition.setValue(c.getAddressAddition());
            } else {
                pickupAddressAddition.clear();
            }
            if (c.getZip() != null) {
                pickupZip.setValue(c.getZip());
            } else {
                pickupZip.clear();
            }
            if (c.getCity() != null) {
                pickupCity.setValue(c.getCity());
            } else {
                pickupCity.clear();
            }
        });

        preloadAddressButton = new Button("Vorbelegte Adressfelder leeren");
        preloadAddressButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        preloadAddressButton.addClickListener(event -> clearAllFields());

        // Pickup address
        pickupCompany = new ComboBox<>("Firma");
        pickupCompany.setPlaceholder("Firmenname");
        pickupCompany.setAllowCustomValue(true);
        setupCompanyAutocomplete(pickupCompany, true); // true für Pickup
        pickupSalutation = new ComboBox<>("Anrede");
        pickupSalutation.setItems("Herr", "Frau", "Divers");
        pickupSalutation.setPlaceholder("Anrede wählen...");
        pickupFirstName = new TextField("Vorname");
        pickupFirstName.setPlaceholder("Vorname");
        pickupFirstName.setRequiredIndicatorVisible(true);
        pickupLastName = new TextField("Nachname");
        pickupLastName.setPlaceholder("Nachname");
        pickupLastName.setRequiredIndicatorVisible(true);
        pickupPhone = new TextField("Telefonnummer");
        pickupPhone.setPlaceholder("Telefonnummer");
        pickupStreet = new TextField("Straße");
        pickupStreet.setPlaceholder("Musterstraße");
        pickupStreet.setRequiredIndicatorVisible(true);
        pickupHouseNumber = new TextField("Hausnummer");
        pickupHouseNumber.setPlaceholder("Hausnummer");
        pickupHouseNumber.setRequiredIndicatorVisible(true);
        pickupAddressAddition = new TextField("Adresszusatz");
        pickupAddressAddition.setPlaceholder("2. OG, Hinterhaus...");
        pickupZip = new TextField("Postleitzahl");
        pickupZip.setPlaceholder("Postleitzahl");
        pickupZip.setRequiredIndicatorVisible(true);
        pickupCity = new TextField("Ort");
        pickupCity.setPlaceholder("Hamburg");
        pickupCity.setRequiredIndicatorVisible(true);
        savePickupAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
        savePickupAddress.setValue(true);

        // Delivery address
        deliveryCompany = new ComboBox<>("Firma");
        deliveryCompany.setPlaceholder("Firmenname");
        deliveryCompany.setAllowCustomValue(true);
        setupCompanyAutocomplete(deliveryCompany, false); // false für Delivery
        deliverySalutation = new ComboBox<>("Anrede");
        deliverySalutation.setItems("Herr", "Frau", "Divers");
        deliverySalutation.setPlaceholder("Anrede wählen...");
        deliveryFirstName = new TextField("Vorname");
        deliveryFirstName.setPlaceholder("Vorname");
        deliveryFirstName.setRequiredIndicatorVisible(true);
        deliveryLastName = new TextField("Nachname");
        deliveryLastName.setPlaceholder("Nachname");
        deliveryLastName.setRequiredIndicatorVisible(true);
        deliveryPhone = new TextField("Telefonnummer");
        deliveryPhone.setPlaceholder("Telefonnummer");
        deliveryStreet = new TextField("Straße");
        deliveryStreet.setPlaceholder("Beispielweg");
        deliveryStreet.setRequiredIndicatorVisible(true);
        deliveryHouseNumber = new TextField("Hausnr");
        deliveryHouseNumber.setPlaceholder("Hausnummer");
        deliveryHouseNumber.setRequiredIndicatorVisible(true);
        deliveryAddressAddition = new TextField("Adresszusatz");
        deliveryAddressAddition.setPlaceholder("Erdgeschoss, links...");
        deliveryZip = new TextField("Postleitzahl");
        deliveryZip.setPlaceholder("Postleitzahl");
        deliveryZip.setRequiredIndicatorVisible(true);
        deliveryCity = new TextField("Ort");
        deliveryCity.setPlaceholder("Berlin");
        deliveryCity.setRequiredIndicatorVisible(true);
        saveDeliveryAddress = new Checkbox("Die Adresse für zukünftige Aufträge speichern.");
        saveDeliveryAddress.setValue(true);

        // Digital processing
        digitalProcessing = new Checkbox("Digitale Abwicklung per App");
        digitalProcessing.setValue(true);
        appUser = new ComboBox<>("App-Nutzer");

        // Load app users for current user and set up the ComboBox
        availableAppUsers = appUserService.findByCurrentUser();
        appUser.setItems(availableAppUsers);
        appUser.setItemLabelGenerator(
                user -> user.getVorname() + " " + user.getNachname() + " (" + user.getEmail() + ")");
        appUser.setPlaceholder("App-Nutzer auswählen...");

        // Price field
        price = new TextField("Preis");
        price.setPlaceholder("Betrag eingeben");
        price.setRequiredIndicatorVisible(true);

        // Erzwinge Komma als Dezimaltrennzeichen: ersetze Punkt beim Tippen
        price.addValueChangeListener(e -> {
            String v = e.getValue();
            if (v != null && v.contains(".")) {
                String replaced = v.replace('.', ',');
                if (!replaced.equals(v))
                    price.setValue(replaced);
            }
        });
        // Date picker fields for appointments
        pickupDate = new DatePicker("Datum");
        pickupDate.setRequiredIndicatorVisible(true);
        deliveryDate = new DatePicker("Datum");
        deliveryDate.setRequiredIndicatorVisible(true);

        // Submit button
        submitButton = new Button("Auftrag anlegen", event -> submit());
        submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
    }

    // Testdaten entfernt

    private void setupLayout() {
        setSizeFull();
        addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX, LumoUtility.FlexDirection.COLUMN,
                LumoUtility.Padding.MEDIUM, LumoUtility.Gap.SMALL);

        add(new ViewToolbar("Neuen Auftrag anlegen"));

        // Create TabSheet for organizing the form
        // TabSheet and Tab references for dynamic label updates
        TabSheet tabSheet = new TabSheet();
        tabSheet.setSizeFull();

        // Tab 1: Customer & Addresses
        addressesTab = tabSheet.add("Auftraggeber & Adressen", createCustomerAndAddressesTab());

        // Tab 2: Appointments & Processing
        appointmentsTab = tabSheet.add("Termine & Verarbeitung", createAppointmentsAndProcessingTab());

        // Tab 3: Cargo
        cargoTab = tabSheet.add("Ladung", createCargoTab());

        // Tab 4: Tasks
        tasksTab = tabSheet.add("Aufgaben", createTasksTab());

        // Tab 5: Price & Submit
        priceTab = tabSheet.add("Preis & Abschluss", createPriceAndSubmitTab());

        add(tabSheet);

        // Add submit button horizontally centered below the tabs
        HorizontalLayout buttonLayout = new HorizontalLayout();
        buttonLayout.setWidthFull();
        buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
        buttonLayout.setPadding(true);
        buttonLayout.add(submitButton);

        add(buttonLayout);
    }

    private Component createCustomerAndAddressesTab() {
        VerticalLayout tabContent = new VerticalLayout();
        tabContent.setSizeFull();
        tabContent.setPadding(true);
        tabContent.setSpacing(true);

        // Customer selection section
        HorizontalLayout customerLayout = new HorizontalLayout();
        customerLayout.setWidthFull();
        customerLayout.setAlignItems(FlexComponent.Alignment.END);
        customerLayout.add(customerSelection, preloadAddressButton);
        customerSelection.setWidth("70%");
        preloadAddressButton.setWidth("30%");

        tabContent.add(customerLayout);

        // Main content layout with two equal columns (50% each)
        HorizontalLayout mainLayout = new HorizontalLayout();
        mainLayout.setWidthFull();
        mainLayout.setSpacing(true);
        mainLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.START);

        // Left column (50%) - Pickup address section
        pickupSection = createPickupSection();
        pickupSection.setWidth("50%");

        // Right column (50%) - Delivery address section
        deliverySection = createDeliverySection();
        deliverySection.setWidth("50%");

        // Setup focus listeners for input fields
        setupInputFieldFocusListeners();

        mainLayout.add(pickupSection, deliverySection);
        tabContent.add(mainLayout);

        return tabContent;
    }

    private Component createAppointmentsAndProcessingTab() {
        VerticalLayout tabContent = new VerticalLayout();
        tabContent.setSizeFull();
        tabContent.setPadding(true);
        tabContent.setSpacing(true);
        tabContent.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);

        // Container with fixed width to center content
        VerticalLayout content = new VerticalLayout();
        content.setPadding(false);
        content.setSpacing(true);
        content.setWidth("720px");
        content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);

        // Row: Digital processing + App user
        HorizontalLayout digitalRow = new HorizontalLayout();
        digitalRow.setWidthFull();
        digitalRow.setAlignItems(FlexComponent.Alignment.BASELINE);
        digitalRow.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        digitalProcessing.getStyle().set("margin-right", "12px");
        digitalRow.add(digitalProcessing);

        // App user selector full width
        appUser.setWidthFull();
        content.add(digitalRow, appUser);

        // Appointment (Pickup)
        H3 pickupApptTitle = new H3("Termin (Abholung)");
        pickupApptTitle.getStyle().set("margin", "0");
        TimePicker pickupTime = new TimePicker("Uhrzeit");
        HorizontalLayout pickupApptRow = new HorizontalLayout(pickupDate, pickupTime);
        pickupApptRow.setWidthFull();
        pickupApptRow.setSpacing(true);
        pickupDate.setWidth("50%");
        pickupTime.setWidth("50%");
        content.add(pickupApptTitle, pickupApptRow);

        // Appointment (Delivery)
        H3 deliveryApptTitle = new H3("Termin (Lieferung)");
        deliveryApptTitle.getStyle().set("margin", "0");
        TimePicker deliveryTime = new TimePicker("Uhrzeit");
        HorizontalLayout deliveryApptRow = new HorizontalLayout(deliveryDate, deliveryTime);
        deliveryApptRow.setWidthFull();
        deliveryApptRow.setSpacing(true);
        deliveryDate.setWidth("50%");
        deliveryTime.setWidth("50%");
        content.add(deliveryApptTitle, deliveryApptRow);

        tabContent.add(content);
        return tabContent;
    }

    private Component createCargoTab() {
        VerticalLayout tabContent = new VerticalLayout();
        tabContent.setSizeFull();
        tabContent.setPadding(true);
        tabContent.setSpacing(true);

        // Add cargo section
        tabContent.add(createCargoSection());

        return tabContent;
    }

    private Component createTasksTab() {
        VerticalLayout tabContent = new VerticalLayout();
        tabContent.setSizeFull();
        tabContent.setPadding(true);
        tabContent.setSpacing(true);

        // Add tasks and notes section
        tabContent.add(createTasksAndNotesSection());

        return tabContent;
    }

    private Component createPriceAndSubmitTab() {
        VerticalLayout tabContent = new VerticalLayout();
        tabContent.setSizeFull();
        tabContent.setPadding(true);
        tabContent.setSpacing(true);
        tabContent.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);

        // Container with fixed width to center content
        VerticalLayout content = new VerticalLayout();
        content.setPadding(false);
        content.setSpacing(true);
        content.setWidth("720px");
        content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);

        // Preis (netto) - moved from createTasksAndNotesSection
        H3 priceTitle = new H3("Preis (netto)");
        priceTitle.getStyle().set("margin", "0");
        content.add(priceTitle, price);

        tabContent.add(content);
        return tabContent;
    }

    private VerticalLayout createPickupSection() {
        VerticalLayout section = new VerticalLayout();
        section.setSpacing(true);
        section.setPadding(true);
        section.setWidthFull();

        // Hellgrauer Rahmen hinzufügen
        section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
        section.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
        section.getStyle().set("background-color", "var(--lumo-base-color)");

        H3 title = new H3("Abholadresse");
        title.getStyle().set("margin", "0");

        HorizontalLayout titleLayout = new HorizontalLayout();
        titleLayout.setWidthFull();
        titleLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        titleLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
        titleLayout.add(title);

        // Alle einzelnen Controls auf volle Breite setzen
        pickupCompany.setWidthFull();
        pickupSalutation.setWidthFull();
        pickupFirstName.setWidthFull();
        pickupLastName.setWidthFull();
        pickupPhone.setWidthFull();
        pickupAddressAddition.setWidthFull();
        savePickupAddress.setWidthFull();

        section.add(titleLayout);
        section.add(pickupCompany);
        section.add(pickupSalutation);
        section.add(pickupFirstName);
        section.add(pickupLastName);
        section.add(pickupPhone);

        HorizontalLayout streetLayout = new HorizontalLayout();
        streetLayout.setWidthFull();
        streetLayout.setSpacing(true);
        streetLayout.add(pickupStreet, pickupHouseNumber);
        pickupStreet.setWidth("70%");
        pickupHouseNumber.setWidth("30%");
        section.add(streetLayout);

        section.add(pickupAddressAddition);

        // zip/city row
        HorizontalLayout zipCityLayout = new HorizontalLayout();
        zipCityLayout.setWidthFull();
        zipCityLayout.setSpacing(true);
        zipCityLayout.add(pickupZip, pickupCity);
        pickupZip.setWidth("30%");
        pickupCity.setWidth("70%");
        section.add(zipCityLayout);

        section.add(savePickupAddress);

        return section;
    }

    private VerticalLayout createDeliverySection() {
        VerticalLayout section = new VerticalLayout();
        section.setSpacing(true);
        section.setPadding(true);
        section.setWidthFull();

        // Hellgrauer Rahmen hinzufügen
        section.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
        section.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
        section.getStyle().set("background-color", "var(--lumo-base-color)");

        H3 title = new H3("Lieferadresse");
        title.getStyle().set("margin", "0");

        HorizontalLayout titleLayout = new HorizontalLayout();
        titleLayout.setWidthFull();
        titleLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        titleLayout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
        titleLayout.add(title);

        // Alle einzelnen Controls auf volle Breite setzen
        deliveryCompany.setWidthFull();
        deliverySalutation.setWidthFull();
        deliveryFirstName.setWidthFull();
        deliveryLastName.setWidthFull();
        deliveryPhone.setWidthFull();
        deliveryAddressAddition.setWidthFull();
        saveDeliveryAddress.setWidthFull();

        section.add(titleLayout);
        section.add(deliveryCompany);
        section.add(deliverySalutation);
        section.add(deliveryFirstName);
        section.add(deliveryLastName);
        section.add(deliveryPhone);

        HorizontalLayout streetLayout = new HorizontalLayout();
        streetLayout.setWidthFull();
        streetLayout.setSpacing(true);
        streetLayout.add(deliveryStreet, deliveryHouseNumber);
        deliveryStreet.setWidth("70%");
        deliveryHouseNumber.setWidth("30%");
        section.add(streetLayout);

        section.add(deliveryAddressAddition);

        HorizontalLayout zipCityLayout = new HorizontalLayout();
        zipCityLayout.setWidthFull();
        zipCityLayout.setSpacing(true);
        zipCityLayout.add(deliveryZip, deliveryCity);
        deliveryZip.setWidth("30%");
        deliveryCity.setWidth("70%");
        section.add(zipCityLayout);

        section.add(saveDeliveryAddress);

        return section;
    }

    private void setupCompanyAutocomplete(ComboBox<String> companyField, boolean isPickup) {
        // Get all customers for the current owner
        List<Customer> allCustomers = customerService.findAllForCurrentOwner();

        // Extract unique company names (filter out null/empty values)
        List<String> companyNames = allCustomers.stream().map(Customer::getCompanyName)
                .filter(name -> name != null && !name.trim().isEmpty()).distinct().sorted().toList();

        // Set items for autocomplete
        companyField.setItems(companyNames);

        // Add selection listener to auto-fill address fields when company is selected
        companyField.addValueChangeListener(event -> {
            String selectedCompany = event.getValue();
            if (selectedCompany == null || selectedCompany.trim().isEmpty()) {
                return;
            }

            // Find the first customer with this company name
            Optional<Customer> matchingCustomer = allCustomers.stream()
                    .filter(c -> selectedCompany.equals(c.getCompanyName())).findFirst();

            if (matchingCustomer.isPresent()) {
                Customer customer = matchingCustomer.get();

                if (isPickup) {
                    // Fill pickup address fields
                    if (customer.getTitle() != null && ("Herr".equalsIgnoreCase(customer.getTitle())
                            || "Frau".equalsIgnoreCase(customer.getTitle())
                            || "Divers".equalsIgnoreCase(customer.getTitle()))) {
                        pickupSalutation.setValue(customer.getTitle());
                    }
                    if (customer.getFirstname() != null)
                        pickupFirstName.setValue(customer.getFirstname());
                    if (customer.getLastName() != null)
                        pickupLastName.setValue(customer.getLastName());
                    if (customer.getTelephone() != null)
                        pickupPhone.setValue(customer.getTelephone());
                    if (customer.getStreet() != null)
                        pickupStreet.setValue(customer.getStreet());
                    if (customer.getHouseNumber() != null)
                        pickupHouseNumber.setValue(customer.getHouseNumber());
                    if (customer.getAddressAddition() != null)
                        pickupAddressAddition.setValue(customer.getAddressAddition());
                    if (customer.getZip() != null)
                        pickupZip.setValue(customer.getZip());
                    if (customer.getCity() != null)
                        pickupCity.setValue(customer.getCity());

                    // Deactivate save checkbox since customer already exists
                    savePickupAddress.setValue(false);
                } else {
                    // Fill delivery address fields
                    if (customer.getTitle() != null && ("Herr".equalsIgnoreCase(customer.getTitle())
                            || "Frau".equalsIgnoreCase(customer.getTitle())
                            || "Divers".equalsIgnoreCase(customer.getTitle()))) {
                        deliverySalutation.setValue(customer.getTitle());
                    }
                    if (customer.getFirstname() != null)
                        deliveryFirstName.setValue(customer.getFirstname());
                    if (customer.getLastName() != null)
                        deliveryLastName.setValue(customer.getLastName());
                    if (customer.getTelephone() != null)
                        deliveryPhone.setValue(customer.getTelephone());
                    if (customer.getStreet() != null)
                        deliveryStreet.setValue(customer.getStreet());
                    if (customer.getHouseNumber() != null)
                        deliveryHouseNumber.setValue(customer.getHouseNumber());
                    if (customer.getAddressAddition() != null)
                        deliveryAddressAddition.setValue(customer.getAddressAddition());
                    if (customer.getZip() != null)
                        deliveryZip.setValue(customer.getZip());
                    if (customer.getCity() != null)
                        deliveryCity.setValue(customer.getCity());

                    // Deactivate save checkbox since customer already exists
                    saveDeliveryAddress.setValue(false);
                }
            }
        });

        // Handle custom values (when user types something not in the list)
        companyField.addCustomValueSetListener(event -> {
            String customValue = event.getDetail();
            companyField.setValue(customValue);

            // Reactivate save checkbox for custom values
            if (isPickup) {
                savePickupAddress.setValue(true);
            } else {
                saveDeliveryAddress.setValue(true);
            }
        });
    }

    private void setupValidation() {
        // Bind pickup address fields with validation
        binder.forField(pickupFirstName).asRequired("").bind(Job::getPickupFirstName, Job::setPickupFirstName);

        binder.forField(pickupLastName).asRequired("").bind(Job::getPickupLastName, Job::setPickupLastName);

        binder.forField(pickupStreet).asRequired("").bind(Job::getPickupStreet, Job::setPickupStreet);

        binder.forField(pickupHouseNumber).asRequired("").bind(Job::getPickupHouseNumber, Job::setPickupHouseNumber);

        binder.forField(pickupZip).asRequired("").bind(Job::getPickupZip, Job::setPickupZip);

        binder.forField(pickupCity).asRequired("").bind(Job::getPickupCity, Job::setPickupCity);

        // Bind delivery address fields with validation
        binder.forField(deliveryFirstName).asRequired("").bind(Job::getDeliveryFirstName, Job::setDeliveryFirstName);

        binder.forField(deliveryLastName).asRequired("").bind(Job::getDeliveryLastName, Job::setDeliveryLastName);

        binder.forField(deliveryStreet).asRequired("").bind(Job::getDeliveryStreet, Job::setDeliveryStreet);

        binder.forField(deliveryHouseNumber).asRequired("").bind(Job::getDeliveryHouseNumber,
                Job::setDeliveryHouseNumber);

        binder.forField(deliveryZip).asRequired("").bind(Job::getDeliveryZip, Job::setDeliveryZip);

        binder.forField(deliveryCity).asRequired("").bind(Job::getDeliveryCity, Job::setDeliveryCity);

        // Bind price field: Komma-Zahlen in Punkt-Zahlen umsetzen, dann nach BigDecimal
        // konvertieren
        binder.forField(price).withNullRepresentation("").asRequired("Preis erforderlich").withConverter((String s) -> {
            if (s == null || s.trim().isEmpty())
                return null;
            String normalized = s.replace(" ", "").replace(".", "").replace(',', '.');
            try {
                return new java.math.BigDecimal(normalized);
            } catch (NumberFormatException ex) {
                throw new NumberFormatException("Ungültiger Betrag");
            }
        }, (java.math.BigDecimal bd) -> bd == null ? "" : bd.toString(), "Ungültiger Betrag")
                .withValidator(value -> value != null && value.compareTo(java.math.BigDecimal.ZERO) > 0,
                        "Der Preis muss größer als 0 sein")
                .bind(Job::getPrice, Job::setPrice);

        // Bind date picker fields with validation
        binder.forField(pickupDate).asRequired("").bind(Job::getPickupDate, Job::setPickupDate);

        binder.forField(deliveryDate).asRequired("").bind(Job::getDeliveryDate, Job::setDeliveryDate);

        // Bind customerSelection field with validation
        binder.forField(customerSelection).asRequired("").bind(Job::getCustomerSelection, Job::setCustomerSelection);

        // Bind optional fields without validation
        binder.bind(pickupCompany, Job::getPickupCompany, Job::setPickupCompany);
        binder.bind(pickupSalutation, Job::getPickupSalutation, Job::setPickupSalutation);
        binder.bind(pickupPhone, Job::getPickupPhone, Job::setPickupPhone);
        binder.bind(pickupAddressAddition, Job::getPickupAddressAddition, Job::setPickupAddressAddition);

        binder.bind(deliveryCompany, Job::getDeliveryCompany, Job::setDeliveryCompany);
        binder.bind(deliverySalutation, Job::getDeliverySalutation, Job::setDeliverySalutation);
        binder.bind(deliveryPhone, Job::getDeliveryPhone, Job::setDeliveryPhone);
        binder.bind(deliveryAddressAddition, Job::getDeliveryAddressAddition, Job::setDeliveryAddressAddition);

        binder.bind(digitalProcessing, Job::isDigitalProcessing, Job::setDigitalProcessing);

        // Bind appUser with converter: AppUser object <-> String ID
        binder.forField(appUser).withConverter(
                // Convert AppUser to String (ID)
                user -> user != null ? user.getId().toHexString() : null,
                // Convert String (ID) back to AppUser
                id -> {
                    if (id == null || id.trim().isEmpty())
                        return null;
                    return availableAppUsers.stream().filter(user -> user.getId().toHexString().equals(id)).findFirst()
                            .orElse(null);
                })
                // Require App-Nutzer when digital processing is enabled
                .withValidator(selectedUserId -> {
                    boolean digital = Boolean.TRUE.equals(digitalProcessing.getValue());
                    boolean hasUser = selectedUserId != null && !selectedUserId.trim().isEmpty();
                    return !digital || hasUser;
                }, "Bitte App-Nutzer auswählen, wenn Digitale Abwicklung aktiv ist")
                .bind(Job::getAppUser, Job::setAppUser);

        // Toggle required indicator for App-Nutzer based on digitalProcessing
        digitalProcessing.addValueChangeListener(e -> {
            boolean required = Boolean.TRUE.equals(e.getValue());
            appUser.setRequiredIndicatorVisible(required);
            triggerValidation();
            updateTabLabels();
        });
        // Also revalidate when appUser changes
        appUser.addValueChangeListener(e -> {
            triggerValidation();
            updateTabLabels();
        });
        // Initialize required indicator state
        appUser.setRequiredIndicatorVisible(Boolean.TRUE.equals(digitalProcessing.getValue()));

        // Set up validation triggers and visual styling
        setupValidationTriggers();

        // Trigger initial validation when view is displayed
        triggerValidation();

        // Update tab labels with initial validation state
        updateTabLabels();
    }

    private void setupValidationTriggers() {
        // List of all required fields
        TextField[] requiredTextFields = { pickupFirstName, pickupLastName, pickupStreet, pickupHouseNumber, pickupZip,
                pickupCity, deliveryFirstName, deliveryLastName, deliveryStreet, deliveryHouseNumber, deliveryZip,
                deliveryCity, price };

        // List of required date fields
        DatePicker[] requiredDateFields = { pickupDate, deliveryDate };

        // Add validation listener for customerSelection ComboBox
        customerSelection.addValueChangeListener(event -> {
            triggerValidation();
            updateTabLabels();
        });

        // Add value change listeners to trigger validation on every change for text
        // fields
        for (TextField field : requiredTextFields) {
            field.addValueChangeListener(event -> {
                triggerValidation();
                updateFieldStyling(field);
                updateTabLabels();
            });

            // Add focus listeners for immediate visual feedback
            field.addFocusListener(event -> updateFieldStyling(field));
            field.addBlurListener(event -> updateFieldStyling(field));

            // Set initial styling
            updateFieldStyling(field);
        }

        // Add value change listeners for date fields
        for (DatePicker field : requiredDateFields) {
            field.addValueChangeListener(event -> {
                triggerValidation();
                updateDateFieldStyling(field);
                updateTabLabels();
            });

            // Add focus listeners for immediate visual feedback
            field.addFocusListener(event -> updateDateFieldStyling(field));
            field.addBlurListener(event -> updateDateFieldStyling(field));

            // Set initial styling
            updateDateFieldStyling(field);
        }
    }

    private void triggerValidation() {
        // Create a temporary job object to trigger validation
        binder.validate();
    }

    private void updateFieldStyling(TextField field) {
        String value = field.getValue();
        boolean isEmpty = value == null || value.trim().isEmpty();

        if (isEmpty) {
            // Apply transparent red background only to the input field, not the label
            field.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
            field.getStyle().set("--vaadin-input-field-border-color", "rgba(255, 0, 0, 0.3)");
        } else {
            // Remove styling when field is filled
            field.getStyle().remove("--vaadin-input-field-background");
            field.getStyle().remove("--vaadin-input-field-border-color");
        }
    }

    private void updateDateFieldStyling(DatePicker field) {
        boolean isEmpty = field.getValue() == null;

        if (isEmpty) {
            // Apply transparent red background only to the input field, not the label
            field.getStyle().set("--vaadin-input-field-background", "rgba(255, 0, 0, 0.1)");
            field.getStyle().set("--vaadin-input-field-border-color", "rgba(255, 0, 0, 0.3)");
        } else {
            // Remove styling when field is filled
            field.getStyle().remove("--vaadin-input-field-background");
            field.getStyle().remove("--vaadin-input-field-border-color");
        }
    }

    private void updateTabLabels() {
        // Check validation state for each tab and update labels with exclamation marks
        updateTabLabel(addressesTab, "Auftraggeber & Adressen", hasAddressValidationErrors());
        updateTabLabel(appointmentsTab, "Termine & Verarbeitung", hasAppointmentValidationErrors());
        updateTabLabel(cargoTab, "Ladung", hasCargoValidationErrors());
        updateTabLabel(tasksTab, "Aufgaben", hasTasksValidationErrors());
        updateTabLabel(priceTab, "Preis & Abschluss", hasPriceValidationErrors());
    }

    private void updateTabLabel(com.vaadin.flow.component.tabs.Tab tab, String baseLabel, boolean hasErrors) {
        if (hasErrors) {
            tab.setLabel(baseLabel + " ⚠️");
        } else {
            tab.setLabel(baseLabel);
        }
    }

    private boolean hasAddressValidationErrors() {
        // Check customer selection
        boolean customerSelectionEmpty = customerSelection.getValue() == null
                || customerSelection.getValue().trim().isEmpty();

        // Check pickup address fields
        boolean pickupErrors = isFieldEmpty(pickupFirstName) || isFieldEmpty(pickupLastName)
                || isFieldEmpty(pickupStreet) || isFieldEmpty(pickupHouseNumber) || isFieldEmpty(pickupZip)
                || isFieldEmpty(pickupCity);

        // Check delivery address fields
        boolean deliveryErrors = isFieldEmpty(deliveryFirstName) || isFieldEmpty(deliveryLastName)
                || isFieldEmpty(deliveryStreet) || isFieldEmpty(deliveryHouseNumber) || isFieldEmpty(deliveryZip)
                || isFieldEmpty(deliveryCity);

        return customerSelectionEmpty || pickupErrors || deliveryErrors;
    }

    private boolean hasAppointmentValidationErrors() {
        return pickupDate.getValue() == null || deliveryDate.getValue() == null;
    }

    private boolean hasCargoValidationErrors() {
        // Check if ALL cargo items have all required fields filled
        // When multiple cargo rows exist, ALL must be complete
        if (cargoItemsState.isEmpty()) {
            return true; // No cargo items at all - show warning
        }

        // Check that ALL cargo items are complete
        // A cargo item is considered complete if it has: Description, Quantity, Weight,
        // Length, Width, Height
        boolean allCargoItemsValid = cargoItemsState.stream()
                .allMatch(cargoItem -> cargoItem != null && cargoItem.getDescription() != null
                        && !cargoItem.getDescription().trim().isEmpty() && cargoItem.getQuantity() != null
                        && cargoItem.getQuantity() > 0 && cargoItem.getWeightKg() != null && cargoItem.getWeightKg() > 0
                        && cargoItem.getLengthMm() != null && cargoItem.getLengthMm() > 0
                        && cargoItem.getWidthMm() != null && cargoItem.getWidthMm() > 0
                        && cargoItem.getHeightMm() != null && cargoItem.getHeightMm() > 0);

        return !allCargoItemsValid; // Return true if ANY cargo item is incomplete (show warning)
    }

    private boolean hasTasksValidationErrors() {
        // Tasks are optional, so no validation errors for tasks
        return false;
    }

    private boolean hasPriceValidationErrors() {
        return isFieldEmpty(price);
    }

    private boolean isFieldEmpty(TextField field) {
        String value = field.getValue();
        return value == null || value.trim().isEmpty();
    }

    private void submit() {
        try {
            Job job = new Job();

            // Zusätzliche Felder, die nicht über den Binder gebunden sind, manuell setzen
            job.setPickupDate(pickupDate.getValue());
            job.setDeliveryDate(deliveryDate.getValue());
            if (remarkArea != null)
                job.setRemark(remarkArea.getValue());

            // Validate all required fields using the binder
            if (binder.writeBeanIfValid(job)) {
                // Additional validation: If digital processing is enabled, app user must be
                // selected
                if (digitalProcessing.getValue() && appUser.getValue() == null) {
                    Notification errorNotification = Notification.show(
                            "Wenn digitale Abwicklung per App aktiviert ist, muss ein App-Nutzer ausgewählt werden.");
                    errorNotification.setDuration(5000);
                    return;
                }

                // Ensure at least one cargo item is provided (tasks may be empty)
                // Definition: Ein Cargo-Item gilt nur als gefüllt, wenn eine Beschreibung
                // vorhanden ist
                List<CargoItem> cargoFilled = cargoItemsState.stream().filter(Objects::nonNull)
                        .filter(ci -> ci.getDescription() != null && !ci.getDescription().isBlank()).toList();

                if (cargoFilled.isEmpty()) {
                    Notification errorNotification = Notification
                            .show("Bitte fügen Sie mindestens eine Ladungszeile hinzu.");
                    errorNotification.setDuration(5000);
                    return;
                }
                // toggle cargo error highlight
                boolean hasCargo = true;
                cargoError.setVisible(!hasCargo);
                if (!hasCargo) {
                    cargoAreaContainer.getStyle().set("border", "1px solid var(--lumo-error-color-50pct)");
                } else {
                    cargoAreaContainer.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
                }

                // NEU: Kunden anlegen, wenn Checkboxen aktiviert
                if (savePickupAddress.getValue()) {
                    Customer pickupCustomer = new Customer();
                    pickupCustomer.setCompanyName(pickupCompany.getValue());
                    pickupCustomer.setTitle(pickupSalutation.getValue());
                    pickupCustomer.setFirstname(pickupFirstName.getValue());
                    pickupCustomer.setLastName(pickupLastName.getValue());
                    pickupCustomer.setTelephone(pickupPhone.getValue());
                    pickupCustomer.setStreet(pickupStreet.getValue());
                    pickupCustomer.setHouseNumber(pickupHouseNumber.getValue());
                    pickupCustomer.setAddressAddition(pickupAddressAddition.getValue());
                    pickupCustomer.setZip(pickupZip.getValue());
                    pickupCustomer.setCity(pickupCity.getValue());
                    addCustomerService.addCustomer(pickupCustomer);
                }
                if (saveDeliveryAddress.getValue()) {
                    Customer deliveryCustomer = new Customer();
                    deliveryCustomer.setCompanyName(deliveryCompany.getValue());
                    deliveryCustomer.setTitle(deliverySalutation.getValue());
                    deliveryCustomer.setFirstname(deliveryFirstName.getValue());
                    deliveryCustomer.setLastName(deliveryLastName.getValue());
                    deliveryCustomer.setTelephone(deliveryPhone.getValue());
                    deliveryCustomer.setStreet(deliveryStreet.getValue());
                    deliveryCustomer.setHouseNumber(deliveryHouseNumber.getValue());
                    deliveryCustomer.setAddressAddition(deliveryAddressAddition.getValue());
                    deliveryCustomer.setZip(deliveryZip.getValue());
                    deliveryCustomer.setCity(deliveryCity.getValue());
                    addCustomerService.addCustomer(deliveryCustomer);
                }

                // All validations passed, save the job with cargo items and tasks (tasks may be
                // empty)
                Job savedJob = addJobService.addJobWithCargo(job, cargoFilled, tasksState);

                // Erfolgsmeldung und Navigation zur Zusammenfassung
                Notification successNotification = Notification
                        .show("Auftrag erfolgreich erstellt! Auftragsnummer: " + savedJob.getJobNumber());
                successNotification.setDuration(2000);
                getUI().ifPresent(ui -> ui.navigate(JobSummaryView.class, savedJob.getId().toHexString()));
            } else {
                // Validation failed, show error message
                Notification errorNotification = Notification
                        .show("Bitte füllen Sie alle Pflichtfelder aus (markiert mit *)");
                errorNotification.setDuration(5000);
            }

        } catch (Exception e) {
            // Other errors
            // Reset cargo error
            if (cargoError != null)
                cargoError.setVisible(false);
            if (cargoAreaContainer != null)
                cargoAreaContainer.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
            Notification errorNotification = Notification.show("Fehler beim Erstellen des Auftrags: " + e.getMessage());
            errorNotification.setDuration(5000);
        }
    }

    // showSummary entfernt; Zusammenfassung als eigene Route

    // Zusammenfassungs-Helfer entfernt (Route übernimmt Darstellung)

    /**
     * Lädt einen bestehenden Entwurf, falls vorhanden
     */
    private void loadDraftIfExists() {
        try {
            String currentUser = getCurrentUsername();
            if (currentUser != null) {
                Optional<Job> draftOpt = addJobService.findCurrentDraft(currentUser);
                if (draftOpt.isPresent()) {
                    Job draft = draftOpt.get();
                    loadJobIntoForm(draft);

                    // Benutzer informieren
                    Notification notification = Notification
                            .show("Entwurf wiederhergestellt. Sie können Ihre Arbeit fortsetzen.");
                    notification.setDuration(4000);
                }
            }
        } catch (Exception e) {
            // Fehler beim Laden des Entwurfs sollten nicht die Anwendung blockieren
            log.warn("Fehler beim Laden des Entwurfs: {}", e.getMessage());
        }
    }

    /**
     * Lädt Job-Daten in das Formular
     */
    private void loadJobIntoForm(Job job) {
        if (job.getCustomerSelection() != null) {
            customerSelection.setValue(job.getCustomerSelection());
        }
    }

    private Component createCargoSection() {
        VerticalLayout wrapper = new VerticalLayout();
        wrapper.setWidthFull();
        wrapper.setSpacing(true);

        cargoAreaContainer = new VerticalLayout();
        cargoAreaContainer.setWidthFull();
        cargoAreaContainer.setSpacing(true);
        cargoAreaContainer.getStyle().set("background", "var(--lumo-base-color)");
        cargoAreaContainer.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
        cargoAreaContainer.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
        cargoAreaContainer.getStyle().set("padding", "var(--lumo-space-m)");

        H3 cargoTitle = new H3("Ladung");
        cargoError = new Span("Bitte fügen Sie mindestens eine Ladungszeile hinzu.");
        cargoError.getStyle().set("color", "var(--lumo-error-text-color)");
        cargoError.getStyle().set("font-size", "var(--lumo-font-size-s)");
        cargoError.setVisible(false);

        wrapper.add(cargoTitle);

        cargoList = new VerticalLayout();
        cargoList.setPadding(false);
        cargoList.setSpacing(true);
        cargoAreaContainer.add(cargoError, cargoList);

        java.util.function.BiConsumer<String, java.util.function.Consumer<HorizontalLayout>> addCargoRow = (iconName,
                afterCreate) -> {
            HorizontalLayout row = new HorizontalLayout();
            row.setWidthFull();
            row.setAlignItems(FlexComponent.Alignment.END);

            ComboBox<String> desc = new ComboBox<>("Beschreibung");
            desc.setItems("Europalette", "Einwegpalette", "Düsseldorfer-Palette", "Gitterboxpalette", "Gitterwagen",
                    "Paket");
            desc.setAllowCustomValue(true);
            desc.setPlaceholder("Wählen Sie eine Option oder geben Sie eigenen Text ein...");
            desc.setWidth("40%");

            IntegerField qty = new IntegerField("Anzahl");
            qty.setMin(1);
            qty.setValue(1);
            qty.setWidth("10%");

            NumberField weight = new NumberField("Gewicht");
            weight.setSuffixComponent(new Span("kg"));
            weight.setWidth("15%");

            NumberField len = new NumberField("Länge");
            len.setSuffixComponent(new Span("mm"));
            len.setWidth("12%");
            NumberField wid = new NumberField("Breite");
            wid.setSuffixComponent(new Span("mm"));
            wid.setWidth("12%");
            NumberField hei = new NumberField("Höhe");
            hei.setSuffixComponent(new Span("mm"));
            hei.setWidth("12%");

            Button remove = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
            remove.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
            remove.addClickListener(e -> {
                int idx = cargoList.getChildren().toList().indexOf(row);
                if (idx >= 0 && idx < cargoItemsState.size()) {
                    cargoItemsState.remove(idx);
                }
                cargoList.remove(row);
                updateTabLabels(); // Update tab validation when cargo item is removed
            });

            row.add(desc, qty, weight, len, wid, hei, remove);
            cargoList.add(row);

            // Ensure backing list is in sync: add new item and bind change listeners
            CargoItem item = new CargoItem();
            cargoItemsState.add(item);

            // Initialize from current inputs
            item.setDescription(desc.getValue());
            item.setQuantity(qty.getValue());
            item.setWeightKg(weight.getValue());
            item.setLengthMm(len.getValue());
            item.setWidthMm(wid.getValue());
            item.setHeightMm(hei.getValue());

            desc.addValueChangeListener(ev -> {
                item.setDescription(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo description changes
            });
            qty.addValueChangeListener(ev -> {
                item.setQuantity(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo quantity changes
            });
            weight.addValueChangeListener(ev -> {
                item.setWeightKg(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo weight changes
            });
            len.addValueChangeListener(ev -> {
                item.setLengthMm(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo length changes
            });
            wid.addValueChangeListener(ev -> {
                item.setWidthMm(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo width changes
            });
            hei.addValueChangeListener(ev -> {
                item.setHeightMm(ev.getValue());
                updateTabLabels(); // Update tab validation when cargo height changes
            });

            if (afterCreate != null)
                afterCreate.accept(row);
        };

        addCargoRow.accept("", r -> {
        }); // Show only one empty row by default

        // Add button to add more cargo rows
        Button addCargoButton = new Button("Ladung hinzufügen", new Icon(VaadinIcon.PLUS));
        addCargoButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        addCargoButton.setWidthFull(); // Make button full width of container
        addCargoButton.addClickListener(e -> addCargoRow.accept("", r -> {
        }));

        cargoAreaContainer.add(addCargoButton);
        wrapper.add(cargoAreaContainer);
        return wrapper;
    }

    private Component createTasksAndNotesSection() {
        VerticalLayout wrapper = new VerticalLayout();
        wrapper.setWidthFull();
        wrapper.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);

        // Fester Content-Container für zentrierte Darstellung
        VerticalLayout content = new VerticalLayout();
        content.setWidth("720px");
        content.setPadding(false);
        content.setSpacing(true);
        content.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);

        // Aufgabentitel
        H3 tasksTitle = new H3("Zu quittierende Aufgaben");
        tasksTitle.getStyle().set("margin", "0");
        content.add(tasksTitle);

        // Dynamische Aufgabenliste
        tasksList = new VerticalLayout();
        tasksList.setPadding(false);
        tasksList.setSpacing(true);

        java.util.function.Consumer<Void> addTask = (v) -> {
            createTaskRow();
        };

        // 1 Beispielzeile
        addTask.accept(null);

        Button addTaskBtn = new Button("Aufgabe hinzufügen", new Icon(VaadinIcon.PLUS));
        addTaskBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        addTaskBtn.addClickListener(e -> addTask.accept(null));

        content.add(tasksList, addTaskBtn);

        // Bemerkung
        H3 remarksTitle = new H3("Bemerkung");
        remarksTitle.getStyle().set("margin", "0");
        remarkArea = new TextArea();
        remarkArea.setPlaceholder("z.B. rückwärtigen Liefereingang benutzen o. ä.");
        remarkArea.setWidthFull();
        remarkArea.setMinHeight("180px");
        content.add(remarksTitle, remarkArea);

        wrapper.add(content);
        return wrapper;
    }

    /**
     * Hilfsmethode zum Abrufen des aktuellen Benutzernamens
     */
    private String getCurrentUsername() {
        try {
            // TODO: Implement actual security service to get current username
            // For demo purposes using fixed value
            return "test@votianlt.de";
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Leert alle Felder im Formular
     */
    private void clearAllFields() {
        // Customer selection
        customerSelection.clear();

        // Pickup address
        pickupCompany.clear();
        pickupSalutation.clear();
        pickupFirstName.clear();
        pickupLastName.clear();
        pickupPhone.clear();
        pickupStreet.clear();
        pickupHouseNumber.clear();
        pickupAddressAddition.clear();
        pickupZip.clear();
        pickupCity.clear();
        savePickupAddress.setValue(false);

        // Delivery address
        deliveryCompany.clear();
        deliverySalutation.clear();
        deliveryFirstName.clear();
        deliveryLastName.clear();
        deliveryPhone.clear();
        deliveryStreet.clear();
        deliveryHouseNumber.clear();
        deliveryAddressAddition.clear();
        deliveryZip.clear();
        deliveryCity.clear();
        saveDeliveryAddress.setValue(false);

        // Digital processing
        digitalProcessing.setValue(true);
        appUser.clear();

        // Price field
        price.clear();

        // Benutzer-Feedback
        Notification.show("Alle Felder wurden geleert", 2000, Notification.Position.BOTTOM_CENTER);
    }

    /**
     * Konfiguriert Focus-Listener für alle Eingabefelder um Drag-and-Drop zu
     * steuern
     */
    private void setupInputFieldFocusListeners() {
        // Customer selection
        customerSelection.addFocusListener(e -> disableDragSources());
        customerSelection.addBlurListener(e -> enableDragSources());

        // Pickup fields
        pickupCompany.addFocusListener(e -> disableDragSources());
        pickupCompany.addBlurListener(e -> enableDragSources());
        pickupSalutation.addFocusListener(e -> disableDragSources());
        pickupSalutation.addBlurListener(e -> enableDragSources());
        pickupFirstName.addFocusListener(e -> disableDragSources());
        pickupFirstName.addBlurListener(e -> enableDragSources());
        pickupLastName.addFocusListener(e -> disableDragSources());
        pickupLastName.addBlurListener(e -> enableDragSources());
        pickupPhone.addFocusListener(e -> disableDragSources());
        pickupPhone.addBlurListener(e -> enableDragSources());
        pickupStreet.addFocusListener(e -> disableDragSources());
        pickupStreet.addBlurListener(e -> enableDragSources());
        pickupHouseNumber.addFocusListener(e -> disableDragSources());
        pickupHouseNumber.addBlurListener(e -> enableDragSources());
        pickupAddressAddition.addFocusListener(e -> disableDragSources());
        pickupAddressAddition.addBlurListener(e -> enableDragSources());
        pickupZip.addFocusListener(e -> disableDragSources());
        pickupZip.addBlurListener(e -> enableDragSources());
        pickupCity.addFocusListener(e -> disableDragSources());
        pickupCity.addBlurListener(e -> enableDragSources());

        // Delivery fields
        deliveryCompany.addFocusListener(e -> disableDragSources());
        deliveryCompany.addBlurListener(e -> enableDragSources());
        deliverySalutation.addFocusListener(e -> disableDragSources());
        deliverySalutation.addBlurListener(e -> enableDragSources());
        deliveryFirstName.addFocusListener(e -> disableDragSources());
        deliveryFirstName.addBlurListener(e -> enableDragSources());
        deliveryLastName.addFocusListener(e -> disableDragSources());
        deliveryLastName.addBlurListener(e -> enableDragSources());
        deliveryPhone.addFocusListener(e -> disableDragSources());
        deliveryPhone.addBlurListener(e -> enableDragSources());
        deliveryStreet.addFocusListener(e -> disableDragSources());
        deliveryStreet.addBlurListener(e -> enableDragSources());
        deliveryHouseNumber.addFocusListener(e -> disableDragSources());
        deliveryHouseNumber.addBlurListener(e -> enableDragSources());
        deliveryAddressAddition.addFocusListener(e -> disableDragSources());
        deliveryAddressAddition.addBlurListener(e -> enableDragSources());
        deliveryZip.addFocusListener(e -> disableDragSources());
        deliveryZip.addBlurListener(e -> enableDragSources());
        deliveryCity.addFocusListener(e -> disableDragSources());
        deliveryCity.addBlurListener(e -> enableDragSources());

        // Digital processing
        appUser.addFocusListener(e -> disableDragSources());
        appUser.addBlurListener(e -> enableDragSources());
    }

    /**
     * Deaktiviert alle Drag-Sources durch CSS
     */
    private void disableDragSources() {
        if (pickupSection != null) {
            pickupSection.getStyle().set("pointer-events", "none");
            pickupSection.getElement().setAttribute("draggable", "false");
        }
        if (deliverySection != null) {
            deliverySection.getStyle().set("pointer-events", "none");
            deliverySection.getElement().setAttribute("draggable", "false");
        }
    }

    /**
     * Aktiviert alle Drag-Sources durch CSS
     */
    private void enableDragSources() {
        if (pickupSection != null) {
            pickupSection.getStyle().remove("pointer-events");
            pickupSection.getElement().setAttribute("draggable", "true");
        }
        if (deliverySection != null) {
            deliverySection.getStyle().remove("pointer-events");
            deliverySection.getElement().setAttribute("draggable", "true");
        }
    }

    private void createTaskRow() {
        VerticalLayout taskContainer = new VerticalLayout();
        taskContainer.setPadding(true);
        taskContainer.setSpacing(true);
        taskContainer.getStyle().set("border", "1px solid var(--lumo-contrast-20pct)");
        taskContainer.getStyle().set("border-radius", "var(--lumo-border-radius-m)");
        taskContainer.getStyle().set("background-color", "var(--lumo-base-color)");
        taskContainer.getStyle().set("position", "relative");

        // Task type selection
        ComboBox<TaskType> taskTypeCombo = new ComboBox<>("Aufgabentyp");
        taskTypeCombo.setItems(TaskType.values());
        taskTypeCombo.setItemLabelGenerator(TaskType::getDisplayName);
        taskTypeCombo.setPlaceholder("Aufgabentyp wählen...");
        taskTypeCombo.setWidthFull();

        // Configuration container for dynamic fields
        VerticalLayout configContainer = new VerticalLayout();
        configContainer.setPadding(false);
        configContainer.setSpacing(true);

        // Red X button positioned in top-right corner
        Button deleteXButton = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
        deleteXButton.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
        deleteXButton.getStyle().set("position", "absolute");
        deleteXButton.getStyle().set("top", "8px");
        deleteXButton.getStyle().set("right", "8px");
        deleteXButton.getStyle().set("z-index", "10");
        deleteXButton.getStyle().set("padding", "4px");
        deleteXButton.getStyle().set("min-width", "24px");
        deleteXButton.getStyle().set("min-height", "24px");
        deleteXButton.addClickListener(e -> {
            int idx = tasksList.getChildren().toList().indexOf(taskContainer);
            if (idx >= 0 && idx < tasksState.size()) {
                tasksState.remove(idx);
                // Reorder remaining tasks to maintain correct sequence
                reorderTasksAfterDeletion();
            }
            tasksList.remove(taskContainer);
        });

        taskContainer.add(taskTypeCombo, configContainer);
        taskContainer.add(deleteXButton);

        // Create Task and add to state with correct order
        BaseTask task = new ConfirmationTask("");
        task.setTaskOrder(tasksState.size()); // Set order based on current position
        tasksState.add(task);

        // Use an array to hold the current task reference (allows modification in
        // lambda)
        final BaseTask[] currentTask = { task };

        taskTypeCombo.addValueChangeListener(ev -> {
            TaskType selectedType = ev.getValue();
            if (selectedType != null) {
                // Create new task instance based on type
                BaseTask newTask = createTaskByType(selectedType);
                BaseTask oldTask = currentTask[0];

                newTask.setCompleted(oldTask.isCompleted());
                newTask.setCompletedAt(oldTask.getCompletedAt());
                newTask.setCompletedBy(oldTask.getCompletedBy());

                // Preserve task-specific properties
                switch (oldTask) {
                    case ConfirmationTask oldConfirmationTask when newTask instanceof ConfirmationTask newConfirmationTask -> newConfirmationTask.setButtonText(oldConfirmationTask.getButtonText());
                    case TodoListTask oldTodoTask when newTask instanceof TodoListTask newTodoTask -> newTodoTask.setTodoItems(oldTodoTask.getTodoItems());
                    case PhotoTask oldPhotoTask when newTask instanceof PhotoTask newPhotoTask -> {
                        newPhotoTask.setMinPhotoCount(oldPhotoTask.getMinPhotoCount());
                        newPhotoTask.setMaxPhotoCount(oldPhotoTask.getMaxPhotoCount());
                    }
                    case BarcodeTask oldBarcodeTask when newTask instanceof BarcodeTask newBarcodeTask -> {
                        newBarcodeTask.setMinBarcodeCount(oldBarcodeTask.getMinBarcodeCount());
                        newBarcodeTask.setMaxBarcodeCount(oldBarcodeTask.getMaxBarcodeCount());
                    }
                    default -> {
                    }
                }

                // Replace in state and preserve order
                int index = tasksState.indexOf(oldTask);
                if (index >= 0) {
                    newTask.setTaskOrder(index); // Preserve the order
                    tasksState.set(index, newTask);
                    currentTask[0] = newTask; // Update the reference
                }

                updateTaskConfiguration(configContainer, newTask);
            }
        });

        // Set initial configuration
        taskTypeCombo.setValue(TaskType.CONFIRMATION);
        updateTaskConfiguration(configContainer, currentTask[0]);

        tasksList.add(taskContainer);
    }

    private BaseTask createTaskByType(TaskType taskType) {
        return switch (taskType) {
        case CONFIRMATION -> new ConfirmationTask("");
        case SIGNATURE -> new SignatureTask();
        case TODOLIST -> new TodoListTask(new ArrayList<>());
        case PHOTO -> new PhotoTask(1, 10);
        case BARCODE -> new BarcodeTask(1, 10);
        case COMMENT -> new CommentTask("", false);
        };
    }

    private void reorderTasksAfterDeletion() {
        // Reorder all tasks in tasksState to maintain correct sequence
        for (int i = 0; i < tasksState.size(); i++) {
            BaseTask task = tasksState.get(i);
            if (task != null) {
                task.setTaskOrder(i); // Reset order to match current position
            }
        }
    }

    private void updateTaskConfiguration(VerticalLayout configContainer, BaseTask task) {
        configContainer.removeAll();

        TaskType taskType = TaskType.valueOf(task.getTaskType());

        switch (taskType) {
        case CONFIRMATION:
            TextField buttonTextField = new TextField("Button-Text");
            buttonTextField.setPlaceholder("z.B. 'Bestätigen', 'Abgeschlossen'");
            buttonTextField.setWidthFull();
            ConfirmationTask confirmationTask = (ConfirmationTask) task;
            buttonTextField.setValue(confirmationTask.getButtonText() != null ? confirmationTask.getButtonText() : "");
            buttonTextField.addValueChangeListener(ev -> {
                // Find the current ConfirmationTask in tasksState and update it
                for (BaseTask stateTask : tasksState) {
                    ((ConfirmationTask) stateTask).setButtonText(ev.getValue());
                }
            });
            configContainer.add(buttonTextField);
            break;

        case SIGNATURE:
            // No additional configuration needed
            Span info = new Span("Keine zusätzliche Konfiguration erforderlich");
            info.getStyle().set("color", "var(--lumo-secondary-text-color)");
            info.getStyle().set("font-style", "italic");
            configContainer.add(info);
            break;

        case TODOLIST:
            VerticalLayout todoContainer = new VerticalLayout();
            todoContainer.setPadding(false);
            todoContainer.setSpacing(true);

            H3 todoTitle = new H3("To-Do Punkte");
            todoTitle.getStyle().set("margin", "0");
            todoContainer.add(todoTitle);

            // Dynamic todo list
            VerticalLayout todoList = new VerticalLayout();
            todoList.setPadding(false);
            todoList.setSpacing(true);

            java.util.function.Consumer<Void> addTodoItem = (v) -> {
                HorizontalLayout todoRow = new HorizontalLayout();
                todoRow.setWidthFull();
                todoRow.setAlignItems(FlexComponent.Alignment.END);

                TextField todoField = new TextField();
                todoField.setPlaceholder("To-Do Punkt");
                todoField.setWidth("100%");

                Button removeTodo = new Button(new Icon(VaadinIcon.CLOSE_SMALL));
                removeTodo.addThemeVariants(ButtonVariant.LUMO_ERROR, ButtonVariant.LUMO_TERTIARY);
                removeTodo.addClickListener(e -> {
                    todoList.remove(todoRow);
                    updateTodoItems(todoList, task);
                });

                todoRow.add(todoField, removeTodo);
                todoRow.setFlexGrow(1, todoField);
                todoList.add(todoRow);

                todoField.addValueChangeListener(ev -> updateTodoItems(todoList, task));
            };

            Button addTodoBtn = new Button("To-Do Punkt hinzufügen", new Icon(VaadinIcon.PLUS));
            addTodoBtn.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
            addTodoBtn.addClickListener(e -> addTodoItem.accept(null));

            // Add initial todo item
            addTodoItem.accept(null);

            todoContainer.add(todoList, addTodoBtn);
            configContainer.add(todoContainer);
            break;

        case PHOTO:
            HorizontalLayout photoLayout = new HorizontalLayout();
            photoLayout.setWidthFull();
            photoLayout.setSpacing(true);

            PhotoTask photoTask = (PhotoTask) task;
            IntegerField minPhotos = new IntegerField("Min. Anzahl Fotos");
            minPhotos.setPlaceholder("1");
            minPhotos.setMin(1);
            minPhotos.setValue(photoTask.getMinPhotoCount() != null ? photoTask.getMinPhotoCount() : 1);

            IntegerField maxPhotos = new IntegerField("Max. Anzahl Fotos");
            maxPhotos.setPlaceholder("10");
            maxPhotos.setMin(1);
            maxPhotos.setValue(photoTask.getMaxPhotoCount() != null ? photoTask.getMaxPhotoCount() : 10);

            photoLayout.add(minPhotos, maxPhotos);

            minPhotos.addValueChangeListener(ev -> {
                photoTask.setMinPhotoCount(ev.getValue());
            });

            maxPhotos.addValueChangeListener(ev -> {
                photoTask.setMaxPhotoCount(ev.getValue());
            });

            configContainer.add(photoLayout);
            break;

        case BARCODE:
            HorizontalLayout barcodeLayout = new HorizontalLayout();
            barcodeLayout.setWidthFull();
            barcodeLayout.setSpacing(true);

            BarcodeTask barcodeTask = (BarcodeTask) task;
            IntegerField minBarcodes = new IntegerField("Min. Anzahl Barcodes");
            minBarcodes.setPlaceholder("1");
            minBarcodes.setMin(1);
            minBarcodes.setValue(barcodeTask.getMinBarcodeCount() != null ? barcodeTask.getMinBarcodeCount() : 1);

            IntegerField maxBarcodes = new IntegerField("Max. Anzahl Barcodes");
            maxBarcodes.setPlaceholder("10");
            maxBarcodes.setMin(1);
            maxBarcodes.setValue(barcodeTask.getMaxBarcodeCount() != null ? barcodeTask.getMaxBarcodeCount() : 10);

            barcodeLayout.add(minBarcodes, maxBarcodes);

            minBarcodes.addValueChangeListener(ev -> {
                barcodeTask.setMinBarcodeCount(ev.getValue());
            });

            maxBarcodes.addValueChangeListener(ev -> {
                barcodeTask.setMaxBarcodeCount(ev.getValue());
            });

            configContainer.add(barcodeLayout);
            break;
        }
    }

    private void updateTodoItems(VerticalLayout todoList, BaseTask task) {
        List<String> todoItems = todoList.getChildren().map(component -> {
            if (component instanceof HorizontalLayout row) {
                TextField field = (TextField) row.getChildren().findFirst().orElse(null);
                return field != null ? field.getValue() : null;
            }
            return null;
        }).filter(Objects::nonNull).filter(item -> !item.trim().isEmpty())
                .collect(java.util.stream.Collectors.toList());

        if (task instanceof TodoListTask) {
            ((TodoListTask) task).setTodoItems(todoItems);
        }
    }

}
