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.formlayout.FormLayout;
import com.vaadin.flow.component.html.H2;
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.PasswordField;
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 de.assecutor.votianlt.model.AppUser;
import de.assecutor.votianlt.pages.service.AppUserService;
import jakarta.annotation.security.RolesAllowed;
import org.springframework.beans.factory.annotation.Autowired;

@PageTitle("Neuen App-Nutzer anlegen")
@Route(value = "add-app-user", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER", "ADMIN" })
public class AddAppUserView extends VerticalLayout {
    private final AppUserService appUserService;
    private final Binder<AppUser> binder = new Binder<>(AppUser.class);

    // Form fields
    private final TextField designationField = new TextField("Bezeichnung (HH H 000)");
    private final TextField firstnameField = new TextField("Vorname");
    private final TextField lastnameField = new TextField("Nachname");
    private final TextField phoneField = new TextField("Telefon (Mobil)");
    private final TextField emailField = new TextField("E-Mail-Adresse");
    private final PasswordField passwordField = new PasswordField("Passwort");
    private final PasswordField confirmPasswordField = new PasswordField("Passwort wiederholen");

    @Autowired
    public AddAppUserView(AppUserService appUserService) {
        this.appUserService = appUserService;
        setSizeFull();
        setPadding(true);
        setSpacing(true);

        // Center content vertically
        setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
        setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);

        // Create main content container
        VerticalLayout contentContainer = new VerticalLayout();
        contentContainer.setWidth("600px");
        contentContainer.setMaxWidth("90%");
        contentContainer.setSpacing(true);
        contentContainer.setPadding(true);
        contentContainer.getStyle().set("background", "var(--lumo-contrast-5pct)");
        contentContainer.getStyle().set("border-radius", "var(--lumo-border-radius)");
        contentContainer.getStyle().set("box-shadow", "var(--lumo-box-shadow-s)");

        // Header with title and back button
        HorizontalLayout header = new HorizontalLayout();
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setSpacing(true);

        H2 title = new H2("Neuen App-Nutzer anlegen");
        title.getStyle().set("margin", "0");

        Button backButton = new Button("Zurück", new Icon(VaadinIcon.ARROW_LEFT));
        backButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
        backButton.addClickListener(e -> navigateBack());

        header.add(title, backButton);
        header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
        contentContainer.add(header);

        // Form layout
        FormLayout formLayout = new FormLayout();
        formLayout.setResponsiveSteps(new FormLayout.ResponsiveStep("0", 1));

        // Configure fields
        designationField.setPlaceholder("(HH H 000)");
        designationField.setWidthFull();
        designationField.setRequiredIndicatorVisible(true);
        designationField.addBlurListener(e -> validateField(designationField, "Kennung ist ein Pflichtfeld"));

        firstnameField.setWidthFull();
        firstnameField.setRequiredIndicatorVisible(true);
        firstnameField.addBlurListener(e -> validateField(firstnameField, "Vorname ist ein Pflichtfeld"));

        lastnameField.setWidthFull();
        lastnameField.setRequiredIndicatorVisible(true);
        lastnameField.addBlurListener(e -> validateField(lastnameField, "Nachname ist ein Pflichtfeld"));

        // Create horizontal layout for firstname and lastname
        HorizontalLayout nameLayout = new HorizontalLayout();
        nameLayout.setWidthFull();
        nameLayout.setSpacing(true);
        nameLayout.add(firstnameField, lastnameField);

        phoneField.setWidthFull();
        phoneField.setRequiredIndicatorVisible(true);
        phoneField.addBlurListener(e -> validateField(phoneField, "Telefonnummer ist ein Pflichtfeld"));


        emailField.setWidthFull();
        emailField.setRequiredIndicatorVisible(true);
        emailField.addBlurListener(e -> validateEmailField());
        // Clear error message when user types a new email
        emailField.addValueChangeListener(e -> {
            emailField.setInvalid(false);
            emailField.setErrorMessage("");
        });

        passwordField.setWidthFull();
        passwordField.setRequired(true);
        passwordField.setRequiredIndicatorVisible(true);
        passwordField.addBlurListener(e -> validatePasswordField());

        confirmPasswordField.setWidthFull();
        confirmPasswordField.setRequired(true);
        confirmPasswordField.setRequiredIndicatorVisible(true);
        confirmPasswordField.addBlurListener(e -> validateConfirmPasswordField());


        // Add fields to form
        formLayout.add(designationField);
        formLayout.add(nameLayout);
        formLayout.add(phoneField);
        formLayout.add(emailField);
        formLayout.add(passwordField);
        formLayout.add(confirmPasswordField);

        contentContainer.add(formLayout);

        // Submit button
        Button submitButton = new Button("App-Nutzer anlegen", e -> createAppUser());
        submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        submitButton.setWidthFull();
        contentContainer.add(submitButton);

        // Add content container to main layout
        add(contentContainer);

        // Setup binder
        setupBinder();

        // Fill with test data
        populateTestData();
    }

    private void setupBinder() {
        // Bind fields to AppUser properties
        binder.forField(designationField).bind(AppUser::getBezeichnung, AppUser::setBezeichnung);
        binder.forField(firstnameField).bind(AppUser::getVorname, AppUser::setVorname);
        binder.forField(lastnameField).bind(AppUser::getNachname, AppUser::setNachname);
        binder.forField(phoneField).bind(AppUser::getTelefon, AppUser::setTelefon);
        binder.forField(emailField).bind(AppUser::getEmail, AppUser::setEmail);
        binder.forField(passwordField).asRequired("Passwort ist erforderlich").bind(AppUser::getPassword,
                AppUser::setPassword);

        // Confirm password field validation
        binder.forField(confirmPasswordField).asRequired("Passwort wiederholen ist erforderlich")
                .withValidator(confirmPassword -> confirmPassword.equals(passwordField.getValue()),
                        "Passwörter stimmen nicht überein")
                .bind(appUser -> "", // Dummy getter - this field is not stored
                        (appUser, value) -> {
                        } // Dummy setter - this field is not stored
                );
    }

    private void createAppUser() {
        // Validate all fields first
        if (!validateAllFields()) {
            Notification.show("Bitte füllen Sie alle Pflichtfelder korrekt aus", 3000, Notification.Position.MIDDLE);
            return;
        }

        try {
            // Create new AppUser object
            AppUser newAppUser = new AppUser();
            binder.writeBean(newAppUser);

            // Save to database
            appUserService.createAppUser(newAppUser);

            // Show success message
            Notification.show("App-Nutzer erfolgreich angelegt", 3000, Notification.Position.MIDDLE);

            // Navigate back to app user list
            navigateBack();

        } catch (ValidationException e) {
            Notification.show("Bitte überprüfen Sie die Eingaben", 3000, Notification.Position.MIDDLE);
        } catch (org.springframework.dao.DuplicateKeyException e) {
            // Handle duplicate email error
            if (e.getMessage().contains("email")) {
                Notification.show("Diese E-Mail-Adresse ist bereits vergeben", 5000, Notification.Position.MIDDLE);
                emailField.focus();
                emailField.setInvalid(true);
                emailField.setErrorMessage("E-Mail-Adresse bereits vorhanden");
            } else {
                Notification.show("Ein Fehler ist aufgetreten: Doppelter Wert gefunden", 5000, Notification.Position.MIDDLE);
            }
        } catch (Exception e) {
            Notification.show("Fehler beim Anlegen des App-Nutzers: " + e.getMessage(), 5000, Notification.Position.MIDDLE);
        }
    }

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

    private void navigateBack() {
        getUI().ifPresent(ui -> ui.navigate("app-user"));
    }

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

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

    private void validatePasswordField() {
        String value = passwordField.getValue();
        if (value == null || value.trim().isEmpty()) {
            passwordField.setInvalid(true);
            passwordField.setErrorMessage("Passwort ist ein Pflichtfeld");
        } else if (value.length() < 6) {
            passwordField.setInvalid(true);
            passwordField.setErrorMessage("Passwort muss mindestens 6 Zeichen lang sein");
        } else {
            passwordField.setInvalid(false);
            passwordField.setErrorMessage("");
        }
    }

    private void validateConfirmPasswordField() {
        String password = passwordField.getValue();
        String confirmPassword = confirmPasswordField.getValue();
        if (confirmPassword == null || confirmPassword.trim().isEmpty()) {
            confirmPasswordField.setInvalid(true);
            confirmPasswordField.setErrorMessage("Bitte bestätigen Sie das Passwort");
        } else if (!confirmPassword.equals(password)) {
            confirmPasswordField.setInvalid(true);
            confirmPasswordField.setErrorMessage("Passwörter stimmen nicht überein");
        } else {
            confirmPasswordField.setInvalid(false);
            confirmPasswordField.setErrorMessage("");
        }
    }


    private boolean validateAllFields() {
        validateField(designationField, "Kennung ist ein Pflichtfeld");
        validateField(firstnameField, "Vorname ist ein Pflichtfeld");
        validateField(lastnameField, "Nachname ist ein Pflichtfeld");
        validateField(phoneField, "Telefonnummer ist ein Pflichtfeld");
        validateEmailField();
        validatePasswordField();
        validateConfirmPasswordField();

        return !designationField.isInvalid() && !firstnameField.isInvalid() && !lastnameField.isInvalid()
                && !phoneField.isInvalid() && !emailField.isInvalid()
                && !passwordField.isInvalid() && !confirmPasswordField.isInvalid();
    }
}
