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.combobox.ComboBox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility;
import de.assecutor.votianlt.model.Customer;
import de.assecutor.votianlt.pages.service.AddCustomerService;
import de.assecutor.votianlt.pages.base.ui.component.ViewToolbar;

import jakarta.annotation.security.RolesAllowed;
import java.time.Clock;

@Route(value = "add-customer", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@PageTitle("Neuen Kunden anlegen")
// @Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Kunden
// anlegen")
@RolesAllowed("USER")
public class AddCustomerView extends Main {
    private final AddCustomerService addCustomerService;

    TextField companyName;
    ComboBox<String> title;
    TextField firstName;
    TextField lastName;
    TextField telephone;
    TextField fax;
    TextField mail;
    TextField street;
    TextField houseNumber;
    TextField addressAddition;
    TextField zip;
    TextField city;
    final Button submitButton;

    private final Binder<Customer> binder = new Binder<>(Customer.class); // Binder f

    public AddCustomerView(AddCustomerService todoService, Clock clock) {
        this.addCustomerService = todoService;

        // Firma (Pflichtfeld)
        companyName = new TextField("Firma");
        companyName.setRequiredIndicatorVisible(true);
        companyName.setWidthFull();
        companyName.addBlurListener(e -> validateField(companyName));

        // Anrede (Dropdown)
        title = new ComboBox<>("Anrede");
        title.setItems("Herr", "Frau", "Divers");
        title.setPlaceholder("Anrede");
        title.setWidthFull();

        // Vorname (Pflichtfeld)
        firstName = new TextField("Vorname");
        firstName.setRequiredIndicatorVisible(true);
        firstName.setWidthFull();
        firstName.addBlurListener(e -> validateField(firstName));

        // Nachname (Pflichtfeld)
        lastName = new TextField("Nachname");
        lastName.setRequiredIndicatorVisible(true);
        lastName.setWidthFull();
        lastName.addBlurListener(e -> validateField(lastName));

        // Telefonnummer (Pflichtfeld)
        telephone = new TextField("Telefonnummer");
        telephone.setRequiredIndicatorVisible(true);
        telephone.setWidthFull();
        telephone.addBlurListener(e -> validateField(telephone));

        // Fax (optional)
        fax = new TextField("Fax");
        fax.setWidthFull();

        // E-Mail (Pflichtfeld)
        mail = new TextField("E-Mail-Adresse");
        mail.setRequiredIndicatorVisible(true);
        mail.setWidthFull();
        mail.addBlurListener(e -> validateEmail());

        // Straße (Pflichtfeld)
        street = new TextField("Straße");
        street.setRequiredIndicatorVisible(true);
        street.addBlurListener(e -> validateField(street));

        // Hausnummer (Pflichtfeld)
        houseNumber = new TextField("Hausnr.");
        houseNumber.setRequiredIndicatorVisible(true);
        houseNumber.addBlurListener(e -> validateField(houseNumber));

        // Adresszusatz (optional)
        addressAddition = new TextField("Adresszusatz");
        addressAddition.setWidthFull();

        // PLZ (Pflichtfeld)
        zip = new TextField("Postleitzahl");
        zip.setRequiredIndicatorVisible(true);
        zip.addBlurListener(e -> validateField(zip));

        // Ort (Pflichtfeld)
        city = new TextField("Ort");
        city.setRequiredIndicatorVisible(true);
        city.addBlurListener(e -> validateField(city));

        // Binder-Konfiguration
        configureBinder();

        // Testdaten setzen
        setTestData();

        // Setze den Button als primär
        submitButton = new Button("Kunden anlegen", event -> submit());
        submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        submitButton.setWidthFull();

        // Erstelle FormLayout wie im Bild
        FormLayout formLayout = new FormLayout();
        formLayout.setMaxWidth("600px");
        formLayout.getStyle().set("margin", "0 auto");

        // Felder hinzufügen (einzeln pro Zeile, außer Straße/Hausnr und PLZ/Ort)
        formLayout.add(companyName);
        formLayout.add(title);
        formLayout.add(firstName);
        formLayout.add(lastName);
        formLayout.add(telephone);
        formLayout.add(fax);
        formLayout.add(mail);

        // Straße und Hausnummer nebeneinander
        formLayout.add(street, houseNumber);

        formLayout.add(addressAddition);

        // PLZ und Ort nebeneinander
        formLayout.add(zip, city);

        formLayout.add(submitButton);

        // Container für zentrierte Darstellung
        VerticalLayout container = new VerticalLayout();
        container.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
        container.setSpacing(true);
        container.add(formLayout);

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

        add(new ViewToolbar("Neuen Kunden anlegen"));
        add(container);
    }

    private void configureBinder() {
        binder.forField(companyName).asRequired("Firma ist ein Pflichtfeld").bind(Customer::getCompanyName,
                Customer::setCompanyName);

        binder.forField(title).bind(Customer::getTitle, Customer::setTitle);

        binder.forField(firstName).asRequired("Vorname ist ein Pflichtfeld").bind(Customer::getFirstname,
                Customer::setFirstname);

        binder.forField(lastName).asRequired("Nachname ist ein Pflichtfeld").bind(Customer::getLastName,
                Customer::setLastName);

        binder.forField(telephone).asRequired("Telefonnummer ist ein Pflichtfeld").bind(Customer::getTelephone,
                Customer::setTelephone);

        binder.forField(fax).bind(Customer::getFax, Customer::setFax);

        binder.forField(mail).asRequired("E-Mail-Adresse ist ein Pflichtfeld")
                .withValidator(email -> email.contains("@"), "Bitte geben Sie eine gültige E-Mail-Adresse ein")
                .bind(Customer::getMail, Customer::setMail);

        binder.forField(street).asRequired("Straße ist ein Pflichtfeld").bind(Customer::getStreet, Customer::setStreet);

        binder.forField(houseNumber).asRequired("Hausnummer ist ein Pflichtfeld").bind(Customer::getHouseNumber,
                Customer::setHouseNumber);

        binder.forField(addressAddition).bind(Customer::getAddressAddition, Customer::setAddressAddition);

        binder.forField(zip).asRequired("Postleitzahl ist ein Pflichtfeld").bind(Customer::getZip, Customer::setZip);

        binder.forField(city).asRequired("Ort ist ein Pflichtfeld").bind(Customer::getCity, Customer::setCity);
    }

    private void setTestData() {
        // No default values - all fields start empty
    }

    private void submit() {
        // First validate all fields
        boolean isValid = validateAllFields();

        if (!isValid) {
            com.vaadin.flow.component.notification.Notification.show("Bitte füllen Sie alle Pflichtfelder aus", 3000,
                    com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
            return;
        }

        try {
            Customer customer = new Customer();
            binder.writeBean(customer);

            addCustomerService.addCustomer(customer);

            // Erfolg anzeigen und zur Kundenliste navigieren
            com.vaadin.flow.component.notification.Notification.show("Kunde erfolgreich angelegt", 3000,
                    com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);

            getUI().ifPresent(ui -> ui.navigate("customers"));

        } catch (ValidationException e) {
            com.vaadin.flow.component.notification.Notification.show("Bitte überprüfen Sie Ihre Eingaben", 3000,
                    com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
        } catch (Exception e) {
            com.vaadin.flow.component.notification.Notification.show("Fehler beim Speichern: " + e.getMessage(), 5000,
                    com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
        }
    }

    private void validateField(TextField field) {
        String value = field.getValue();
        if (value == null || value.trim().isEmpty()) {
            field.setInvalid(true);
            field.setErrorMessage("Dieses Feld ist ein Pflichtfeld");
        } else {
            field.setInvalid(false);
            field.setErrorMessage("");
        }
    }

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

    private boolean validateAllFields() {
        validateField(companyName);
        validateField(firstName);
        validateField(lastName);
        validateField(telephone);
        validateField(street);
        validateField(houseNumber);
        validateField(zip);
        validateField(city);
        validateEmail();

        return !companyName.isInvalid() && !firstName.isInvalid() && !lastName.isInvalid()
                && !telephone.isInvalid() && !mail.isInvalid() && !street.isInvalid()
                && !houseNumber.isInvalid() && !zip.isInvalid() && !city.isInvalid();
    }
}
