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.HasDynamicTitle;
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)
// @Menu(order = 0, icon = "vaadin:clipboard-check", title = "Neuen Kunden
// anlegen")
@RolesAllowed("USER")
public class AddCustomerView extends Main implements HasDynamicTitle {
    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 (optional; auch Privatpersonen können im Adressbuch stehen)
        companyName = new TextField(getTranslation("profile.company"));
        companyName.setWidthFull();

        // Anrede (Dropdown)
        title = new ComboBox<>(getTranslation("addjob.address.salutation"));
        title.setItems(getTranslation("addjob.salutation.mr"), getTranslation("addjob.salutation.ms"),
                getTranslation("addjob.salutation.other"));
        title.setPlaceholder(getTranslation("addjob.address.salutation.placeholder"));
        title.setWidthFull();

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

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

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

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

        // E-Mail (optional)
        mail = new TextField(getTranslation("profile.email"));
        mail.setWidthFull();
        mail.addBlurListener(e -> validateEmail());

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

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

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

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

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

        // Binder-Konfiguration
        configureBinder();

        // Testdaten setzen
        setTestData();

        // Setze den Button als primär
        submitButton = new Button(getTranslation("addcustomer.button.submit"), 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.addClassNames("form-shell", "form-card");
        container.add(formLayout);

        setSizeFull();
        addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX, LumoUtility.FlexDirection.COLUMN,
                LumoUtility.Padding.MEDIUM, LumoUtility.Gap.SMALL);
        addClassName("form-page");

        add(new ViewToolbar(getTranslation("addcustomer.title")));
        add(container);
    }

    private void configureBinder() {
        binder.forField(companyName).bind(Customer::getCompanyName, Customer::setCompanyName);

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

        binder.forField(firstName).asRequired(getTranslation("profile.validation.firstname.required"))
                .bind(Customer::getFirstname, Customer::setFirstname);

        binder.forField(lastName).asRequired(getTranslation("profile.validation.lastname.required"))
                .bind(Customer::getLastName, Customer::setLastName);

        binder.forField(telephone).asRequired(getTranslation("profile.validation.phone")).bind(Customer::getTelephone,
                Customer::setTelephone);

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

        binder.forField(mail)
                .withValidator(email -> email == null || email.isBlank() || email.contains("@"),
                        getTranslation("profile.validation.email.invalid"))
                .bind(Customer::getMail, Customer::setMail);

        binder.forField(street).asRequired(getTranslation("profile.validation.street.required"))
                .bind(Customer::getStreet, Customer::setStreet);

        binder.forField(houseNumber).asRequired(getTranslation("profile.validation.housenr.required"))
                .bind(Customer::getHouseNumber, Customer::setHouseNumber);

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

        binder.forField(zip).asRequired(getTranslation("profile.validation.zip.required")).bind(Customer::getZip,
                Customer::setZip);

        binder.forField(city).asRequired(getTranslation("profile.validation.city.required")).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(
                    getTranslation("addcustomer.notification.validation"), 3000,
                    com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
            return;
        }

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

            boolean created = addCustomerService.addCustomer(customer);
            if (!created) {
                com.vaadin.flow.component.notification.Notification.show(
                        getTranslation("addcustomer.notification.duplicate"), 5000,
                        com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
                return;
            }

            com.vaadin.flow.component.notification.Notification.show(getTranslation("addcustomer.notification.success"),
                    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(getTranslation("addcustomer.notification.check"),
                    3000, com.vaadin.flow.component.notification.Notification.Position.TOP_CENTER);
        } catch (Exception e) {
            com.vaadin.flow.component.notification.Notification.show(
                    getTranslation("addcustomer.notification.error", 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(getTranslation("addcustomer.validation.required"));
        } else {
            field.setInvalid(false);
            field.setErrorMessage("");
        }
    }

    private void validateEmail() {
        String value = mail.getValue();
        if (value != null && !value.trim().isEmpty() && !value.contains("@")) {
            mail.setInvalid(true);
            mail.setErrorMessage(getTranslation("profile.validation.email.invalid"));
        } else {
            mail.setInvalid(false);
            mail.setErrorMessage("");
        }
    }

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

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

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