package de.thpeetz.kontor.admin.views;

import de.thpeetz.kontor.admin.data.Assignment;
import org.springframework.context.annotation.Scope;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;

import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;

import de.thpeetz.kontor.admin.AdminConstants;
import de.thpeetz.kontor.admin.services.AdminService;
import de.thpeetz.kontor.common.views.MainLayout;
import jakarta.annotation.security.RolesAllowed;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringComponent
@Scope("prototype")
@RolesAllowed("ROLE_ADMIN")
@Route(value = AdminConstants.ASSIGNMENT_ROUTE, layout = MainLayout.class)
@PageTitle("Authorization | Admin | Kontor")
public class AssignmentView extends VerticalLayout {

    Grid<Assignment> grid = new Grid<>(Assignment.class);
    AssignmentForm form;
    AdminService service;

    public AssignmentView(AdminService service) {
        this.service = service;
        addClassName("assignment-view");
        setSizeFull();
        configureGrid();
        configureForm();

        add(getToolbar(), getContent());
        updateList();
    }

    private void configureGrid() {
        grid.addClassName("assignment-grid");
        grid.setSizeFull();
        grid.setColumns("profile.userName", "permission.name");
        grid.getColumns().forEach(col -> col.setAutoWidth(true));
        grid.asSingleSelect().addValueChangeListener(event -> editAssignment(event.getValue()));
    }

    private void configureForm() {
        form = new AssignmentForm(service.findAllProfiles(), service.findAllPermissions());
        form.setWidth("25em");
        form.addSaveListener(this::saveAssignment);
        form.addDeleteListener(this::deleteAssignment);
        form.addCloseListener(e -> closeEditor());
    }

    private void saveAssignment(AssignmentForm.SaveEvent event) {
        Assignment assignment = event.getAssignment();
        service.saveAssignment(assignment);
        updateList();
        closeEditor();
    }

    private void deleteAssignment(AssignmentForm.DeleteEvent event) {
        service.deleteAssignment(event.getAssignment());
        updateList();
        closeEditor();
    }

    private Component getContent() {
        HorizontalLayout content = new HorizontalLayout(grid, form);
        content.setFlexGrow(2, grid);
        content.setFlexGrow(1, form);
        content.addClassName("content");
        content.setSizeFull();
        return content;
    }

    private HorizontalLayout getToolbar() {
        Button addAuthorizationMaxtrixButton = new Button("Add permission", click -> addAssignment());
        HorizontalLayout toolbar = new HorizontalLayout(addAuthorizationMaxtrixButton);
        toolbar.addClassName("toolbar");
        return toolbar;
    }

    public void editAssignment(Assignment assignment) {
        if (assignment == null) {
            closeEditor();
        } else {
            form.setAssignment(assignment);
            form.setVisible(true);
            addClassName("editing");
        }
    }

    public void closeEditor() {
        form.setAssignment(null);
        form.setVisible(false);
        removeClassName("editing");
    }

    private void addAssignment() {
        grid.asSingleSelect().clear();
        editAssignment(new Assignment());
    }

    private void updateList() {
        grid.setItems(service.findAllAssignments());
    }
}
