package com.ecep.contract.controller.permission;

import java.util.List;

import org.controlsfx.control.ListSelectionView;
import org.springframework.data.domain.Pageable;

import com.ecep.contract.model.EmployeeRole;
import com.ecep.contract.model.Function;
import com.ecep.contract.util.ParamUtils;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.Tab;

public class EmployeeRoleTabSkinFunctions extends AbstEmployeeRoleBasedTabSkin {

    private final SimpleBooleanProperty changed = new SimpleBooleanProperty(false);
    private ListSelectionView<Function> functionsField;

    public EmployeeRoleTabSkinFunctions(EmployeeRoleWindowController controller) {
        super(controller);
    }

    @Override
    public void initializeUIComponents() {
        super.initializeUIComponents();
        functionsField = controller.functionsField;
    }

    @Override
    public Tab getTab() {
        return controller.functionsTab;
    }

    @Override
    public void initializeTab() {
        Tab tab = getTab();
        if (viewModel.getSystemAdministrator().get()) {
            tab.setDisable(true);
            return;
        }

        initializeListView();
        loadSelectedRoles();
    }

    private void loadSelectedRoles() {
        List<Function> selectedRoles = getRoleService().getFunctionsByRoleId(viewModel.getId().get());
        if (selectedRoles != null) {
            functionsField.getTargetItems().setAll(selectedRoles);
        }
        changed.set(false);
    }

    private void initializeListView() {
        // 非系统内置账户
        List<Function> roles = getFunctionService()
                .findAll(ParamUtils.builder().equals("active", true).build(), Pageable.ofSize(500)).getContent();

        functionsField.getSourceItems().setAll(roles);
        functionsField.setCellFactory(param -> {
            return new ListCell<>() {
                @Override
                protected void updateItem(Function item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null || empty) {
                        setText(null);
                    } else {
                        setText(item.getName());
                    }
                }
            };
        });

        functionsField.getTargetItems().addListener((ListChangeListener<Function>) change -> {
            while (change.next()) {
                List<? extends Function> added = change.getAddedSubList();
                List<? extends Function> removed = change.getRemoved();
                if (!added.isEmpty() || !removed.isEmpty()) {
                    changed.set(true);
                }
            }
        });

        Node targetFooter = functionsField.getTargetFooter();
        if (targetFooter instanceof Button btn) {
            initializeSaveButton(btn);
        }
        targetFooter.disableProperty().bind(changed.not());
    }

    private void initializeSaveButton(Button button) {
        button.setOnAction(this::saveRoles);
    }

    private void saveRoles(ActionEvent event) {
        EmployeeRole entity = getEntity();
        entity.setFunctions(functionsField.getTargetItems());
        save(entity);
        loadSelectedRoles();
    }
}
