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.BeforeEvent;
import com.vaadin.flow.router.HasUrlParameter;
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.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;

@Route(value = "edit-app-user", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER", "ADMIN" })
public class EditAppUserView extends VerticalLayout implements HasUrlParameter<String>, HasDynamicTitle {

    private final AppUserService appUserService;
    private AppUser appUser;
    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 changePasswordField = new PasswordField();
    private final PasswordField confirmChangePasswordField = new PasswordField();

    @Autowired
    public EditAppUserView(AppUserService appUserService) {
        this.appUserService = appUserService;
        setSizeFull();
        setPadding(true);
        addClassName("form-page");
        setSpacing(true);
        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"));
        changePasswordField.setLabel(getTranslation("editappuser.password.change"));
        confirmChangePasswordField.setLabel(getTranslation("editappuser.password.change.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("editappuser.title"));
        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();

        firstnameField.setWidthFull();
        lastnameField.setWidthFull();

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

        phoneField.setWidthFull();
        emailField.setWidthFull();

        // Configure password fields
        changePasswordField.setWidthFull();
        changePasswordField.setPlaceholder(getTranslation("editappuser.password.placeholder"));
        confirmChangePasswordField.setWidthFull();
        confirmChangePasswordField.setPlaceholder(getTranslation("editappuser.password.placeholder"));

        // Add fields to form
        formLayout.add(designationField);
        formLayout.add(nameLayout);
        formLayout.add(phoneField);
        formLayout.add(emailField);
        formLayout.add(changePasswordField);
        formLayout.add(confirmChangePasswordField);

        contentContainer.add(formLayout);

        // Buttons
        HorizontalLayout buttonLayout = new HorizontalLayout();
        buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.CENTER);
        buttonLayout.setWidthFull();

        Button saveButton = new Button(getTranslation("button.savechanges"), e -> saveAppUser());
        saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        Button deleteButton = new Button(getTranslation("button.delete"), e -> deleteAppUser());
        deleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR);

        buttonLayout.add(saveButton, deleteButton);
        buttonLayout.setSpacing(true);
        contentContainer.add(buttonLayout);

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

        // Setup binder
        setupBinder();
    }

    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);
    }

    @Override
    public void setParameter(BeforeEvent event, String parameter) {
        try {
            ObjectId appUserId = new ObjectId(parameter);
            appUser = appUserService.findById(appUserId);

            // Load app user data into form
            binder.readBean(appUser);

        } catch (IllegalArgumentException e) {
            Notification.show(getTranslation("editappuser.notification.invalid.id"), 3000,
                    Notification.Position.MIDDLE);
            navigateBack();
        }
    }

    private void saveAppUser() {
        try {
            // Validate password fields first
            if (!validatePasswordFields()) {
                return;
            }

            // Save current password to restore if not changing
            String originalPassword = appUser.getPassword();

            binder.writeBean(appUser);

            // Handle password change logic
            String newPassword = changePasswordField.getValue();
            String confirmPassword = confirmChangePasswordField.getValue();

            if (newPassword != null && !newPassword.trim().isEmpty()) {
                // User wants to change password
                if (confirmPassword != null && newPassword.equals(confirmPassword)) {
                    // Passwords match, set new password for hashing
                    appUser.setPassword(newPassword);
                } else {
                    Notification.show(getTranslation("editappuser.notification.password.mismatch"), 3000,
                            Notification.Position.MIDDLE);
                    return;
                }
            } else {
                // No password change requested, restore original password
                appUser.setPassword(originalPassword);
            }

            appUserService.updateAppUser(appUser);
            Notification.show(getTranslation("editappuser.notification.saved"), 3000, Notification.Position.MIDDLE);
            navigateBack();
        } catch (ValidationException e) {
            Notification.show(getTranslation("editappuser.notification.check"), 3000, Notification.Position.MIDDLE);
        }
    }

    private boolean validatePasswordFields() {
        String newPassword = changePasswordField.getValue();
        String confirmPassword = confirmChangePasswordField.getValue();

        // If one field is filled, both must be filled
        boolean newPasswordFilled = newPassword != null && !newPassword.trim().isEmpty();
        boolean confirmPasswordFilled = confirmPassword != null && !confirmPassword.trim().isEmpty();

        if (newPasswordFilled && !confirmPasswordFilled) {
            Notification.show(getTranslation("editappuser.notification.password.confirm"), 3000,
                    Notification.Position.MIDDLE);
            return false;
        }

        if (!newPasswordFilled && confirmPasswordFilled) {
            Notification.show(getTranslation("editappuser.notification.password.enter"), 3000,
                    Notification.Position.MIDDLE);
            return false;
        }

        // If both are filled, they must match
        if (newPasswordFilled && confirmPasswordFilled && newPassword != null && !newPassword.equals(confirmPassword)) {
            Notification.show(getTranslation("editappuser.notification.password.mismatch"), 3000,
                    Notification.Position.MIDDLE);
            return false;
        }

        return true;
    }

    private void deleteAppUser() {
        // Show confirmation dialog
        com.vaadin.flow.component.dialog.Dialog confirmDialog = new com.vaadin.flow.component.dialog.Dialog();
        confirmDialog.add(getTranslation("editappuser.dialog.delete.text"));

        HorizontalLayout buttonLayout = new HorizontalLayout();
        Button confirmDeleteButton = new Button(getTranslation("editappuser.dialog.delete.confirm"), e -> {
            if (appUser != null && appUser.getId() != null) {
                appUserService.deleteById(appUser.getId());
                Notification.show(getTranslation("editappuser.notification.deleted"), 3000,
                        Notification.Position.MIDDLE);
                confirmDialog.close();
                navigateBack();
            }
        });
        confirmDeleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR);

        Button cancelDeleteButton = new Button(getTranslation("button.cancel"), e -> confirmDialog.close());
        cancelDeleteButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);

        buttonLayout.add(confirmDeleteButton, cancelDeleteButton);
        buttonLayout.setSpacing(true);
        confirmDialog.add(buttonLayout);

        confirmDialog.open();
    }

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

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