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.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.HasDynamicTitle;
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;

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

    // Form fields - labels set in constructor
    private final TextField designationField = new TextField();
    private final TextField firstnameField = new TextField();
    private final TextField lastnameField = new TextField();
    private final TextField phoneField = new TextField();
    private final TextField emailField = new TextField();
    private final PasswordField passwordField = new PasswordField();
    private final PasswordField confirmPasswordField = new PasswordField();

    @Autowired
    public AddAppUserView(AppUserService appUserService) {
        this.appUserService = appUserService;
        setSizeFull();
        setPadding(true);
        setSpacing(true);
        addClassName("form-page");
        setJustifyContentMode(FlexComponent.JustifyContentMode.START);
        setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
        getStyle().set("overflow", "auto");

        // Set field labels via i18n
        designationField.setLabel(getTranslation("addappuser.designation"));
        firstnameField.setLabel(getTranslation("profile.firstname"));
        lastnameField.setLabel(getTranslation("profile.lastname"));
        phoneField.setLabel(getTranslation("addappuser.phone"));
        emailField.setLabel(getTranslation("profile.email"));
        passwordField.setLabel(getTranslation("addappuser.password"));
        confirmPasswordField.setLabel(getTranslation("addappuser.password.confirm"));

        // Create main content container
        VerticalLayout contentContainer = new VerticalLayout();
        contentContainer.setWidthFull();
        contentContainer.setMaxWidth("100%");
        contentContainer.setSpacing(true);
        contentContainer.setPadding(true);
        contentContainer.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
        contentContainer.addClassNames("form-shell", "form-card");

        // Header
        HorizontalLayout header = new HorizontalLayout();
        header.setWidthFull();
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setSpacing(true);
        header.addClassName("form-header");

        H2 title = new H2(getTranslation("addappuser.title"));
        title.getStyle().set("margin", "0");
        title.addClassName("form-title");

        header.add(title);
        contentContainer.add(header);

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

        // Configure fields
        designationField.setPlaceholder("(HH H 000)");
        designationField.setWidthFull();
        designationField.setRequiredIndicatorVisible(true);
        designationField.addBlurListener(
                e -> validateField(designationField, getTranslation("addappuser.validation.designation")));

        firstnameField.setWidthFull();
        firstnameField.setRequiredIndicatorVisible(true);
        firstnameField
                .addBlurListener(e -> validateField(firstnameField, getTranslation("profile.validation.firstname")));

        lastnameField.setWidthFull();
        lastnameField.setRequiredIndicatorVisible(true);
        lastnameField.addBlurListener(e -> validateField(lastnameField, getTranslation("profile.validation.lastname")));

        // 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, getTranslation("addappuser.validation.phone")));

        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(getTranslation("addappuser.button.submit"), 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(getTranslation("addappuser.validation.password.required"))
                .bind(AppUser::getPassword, AppUser::setPassword);

        // Confirm password field validation
        binder.forField(confirmPasswordField).asRequired(getTranslation("addappuser.validation.password.confirm"))
                .withValidator(confirmPassword -> confirmPassword.equals(passwordField.getValue()),
                        getTranslation("addappuser.validation.password.mismatch"))
                .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(getTranslation("addappuser.notification.validation"), 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(getTranslation("addappuser.notification.success"), 3000, Notification.Position.MIDDLE);

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

        } catch (ValidationException e) {
            Notification.show(getTranslation("addappuser.notification.check"), 3000, Notification.Position.MIDDLE);
        } catch (org.springframework.dao.DuplicateKeyException e) {
            // Handle duplicate email error
            if (e.getMessage().contains("email")) {
                Notification.show(getTranslation("addappuser.notification.email.duplicate"), 5000,
                        Notification.Position.MIDDLE);
                emailField.focus();
                emailField.setInvalid(true);
                emailField.setErrorMessage(getTranslation("addappuser.notification.email.duplicate"));
            } else {
                Notification.show(getTranslation("addappuser.notification.check"), 5000, Notification.Position.MIDDLE);
            }
        } catch (Exception e) {
            Notification.show(getTranslation("addappuser.notification.error", 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(getTranslation("addappuser.validation.email.required"));
        } else if (!value.contains("@") || !value.contains(".")) {
            emailField.setInvalid(true);
            emailField.setErrorMessage(getTranslation("addappuser.validation.email.invalid"));
        } else {
            emailField.setInvalid(false);
            emailField.setErrorMessage("");
        }
    }

    private void validatePasswordField() {
        String value = passwordField.getValue();
        if (value == null || value.trim().isEmpty()) {
            passwordField.setInvalid(true);
            passwordField.setErrorMessage(getTranslation("addappuser.validation.password.required"));
        } else if (value.length() < 6) {
            passwordField.setInvalid(true);
            passwordField.setErrorMessage(getTranslation("addappuser.validation.password.min"));
        } 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(getTranslation("addappuser.validation.password.confirm"));
        } else if (!confirmPassword.equals(password)) {
            confirmPasswordField.setInvalid(true);
            confirmPasswordField.setErrorMessage(getTranslation("addappuser.validation.password.mismatch"));
        } else {
            confirmPasswordField.setInvalid(false);
            confirmPasswordField.setErrorMessage("");
        }
    }

    private boolean validateAllFields() {
        validateField(designationField, getTranslation("addappuser.validation.designation"));
        validateField(firstnameField, getTranslation("profile.validation.firstname"));
        validateField(lastnameField, getTranslation("profile.validation.lastname"));
        validateField(phoneField, getTranslation("addappuser.validation.phone"));
        validateEmailField();
        validatePasswordField();
        validateConfirmPasswordField();

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

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