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


@PageTitle("App-Nutzer bearbeiten")
@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> {

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

    @Autowired
    public EditAppUserView(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("App-Nutzer bearbeiten");
        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();

        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("Leer lassen, wenn nicht ändern");
        confirmChangePasswordField.setWidthFull();
        confirmChangePasswordField.setPlaceholder("Leer lassen, wenn nicht ändern");

        // Configure device dropdown

        // 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("Speichern", e -> saveAppUser());
        saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);

        Button deleteButton = new Button("Löschen", 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("Ungültige App-Nutzer-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("Passwörter stimmen nicht überein", 3000, Notification.Position.MIDDLE);
                    return;
                }
            } else {
                // No password change requested, restore original password
                appUser.setPassword(originalPassword);
            }


            appUserService.updateAppUser(appUser);
            Notification.show("App-Nutzer erfolgreich gespeichert", 3000, Notification.Position.MIDDLE);
            navigateBack();
        } catch (ValidationException e) {
            Notification.show("Bitte überprüfen Sie die Eingaben", 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("Bitte bestätigen Sie das neue Passwort", 3000, Notification.Position.MIDDLE);
            return false;
        }

        if (!newPasswordFilled && confirmPasswordFilled) {
            Notification.show("Bitte geben Sie das neue Passwort ein", 3000, Notification.Position.MIDDLE);
            return false;
        }

        // If both are filled, they must match
        if (newPasswordFilled && confirmPasswordFilled && newPassword != null && !newPassword.equals(confirmPassword)) {
            Notification.show("Passwörter stimmen nicht überein", 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("Möchten Sie diesen App-Nutzer wirklich löschen?");

        HorizontalLayout buttonLayout = new HorizontalLayout();
        Button confirmDeleteButton = new Button("Ja, löschen", e -> {
            if (appUser != null && appUser.getId() != null) {
                appUserService.deleteById(appUser.getId());
                Notification.show("App-Nutzer erfolgreich gelöscht", 3000, Notification.Position.MIDDLE);
                confirmDialog.close();
                navigateBack();
            }
        });
        confirmDeleteButton.addThemeVariants(ButtonVariant.LUMO_ERROR);

        Button cancelDeleteButton = new Button("Abbrechen", e -> confirmDialog.close());

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

        confirmDialog.open();
    }

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