package com.ecep.contract.controller.vendor.group;

import java.util.Arrays;
import java.util.List;

import org.controlsfx.control.ListSelectionView;

import com.ecep.contract.ContractFileType;
import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.model.ContractFileTypeLocal;
import com.ecep.contract.model.VendorGroupRequireFileType;
import com.ecep.contract.service.ContractFileService;
import com.ecep.contract.service.ContractFileTypeService;
import com.ecep.contract.service.VendorGroupRequireFileTypeService;

import impl.org.controlsfx.skin.ListSelectionViewSkin;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Skin;
import javafx.scene.control.Tab;

public class VendorGroupRequireFilesTabSkin extends AbstVendorGroupBasedTabSkin implements TabSkin {

    private final SimpleBooleanProperty changed = new SimpleBooleanProperty(false);
    private ListSelectionView<ContractFileType> fileTypesField;
    private final ObservableMap<ContractFileType, ContractFileTypeLocal> fileTypeLocalMap = FXCollections
            .observableHashMap();

    public VendorGroupRequireFilesTabSkin(VendorGroupWindowController controller) {
        super(controller);
    }

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

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

    @Override
    public void initializeTab() {
        initializeListView();
        loadSelectedRoles();
        fileTypeLocalMap.putAll(getContractFileTypeService().findAll(getLocale()));
    }

    private void loadSelectedRoles() {
        List<VendorGroupRequireFileType> list = getRequireFileTypeService().findByGroupId(viewModel.getId().get());
        List<ContractFileType> types = list.stream().map(VendorGroupRequireFileType::getFileType).toList();
        fileTypesField.getTargetItems().setAll(types);
        changed.set(false);
    }

    private void initializeListView() {

        List<ContractFileType> types = Arrays.stream(ContractFileType.values())
                .filter(ContractFileType::isSupportVendor).toList();
        fileTypesField.getSourceItems().setAll(types);
        fileTypesField.setCellFactory(param -> new ListCell<>() {
            @Override
            protected void updateItem(ContractFileType item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                } else {
                    ContractFileTypeLocal local = fileTypeLocalMap.get(item);
                    if (local == null) {
                        setText(item.name());
                    } else {
                        setText(local.getValue());
                    }
                }
            }
        });

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

        Node targetFooter = fileTypesField.getTargetFooter();
        if (targetFooter instanceof Button btn) {
            initializeSaveButton(btn);
        }

        Skin<?> skin = fileTypesField.getSkin();
        if (skin instanceof ListSelectionViewSkin<?> viewSkin) {
            ListView<?> targetListView = viewSkin.getTargetListView();
            targetListView.setOnMouseClicked(event -> {
                if (event.getClickCount() == 2) {
                    ContractFileType selectedItem = (ContractFileType) targetListView.getSelectionModel()
                            .getSelectedItem();
                    if (selectedItem != null) {
                        // saveRoles(selectedItem);
                        setStatus("selected " + selectedItem);
                    }
                }
            });
        }

        targetFooter.disableProperty().bind(changed.not());
    }

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

    private void saveRequireFileTypes(ActionEvent event) {
        List<VendorGroupRequireFileType> list = getRequireFileTypeService().findByGroupId(viewModel.getId().get());
        ObservableList<ContractFileType> types = fileTypesField.getTargetItems();
        // 保存 types ，list 中是已经存储的，如果types 中没有则删除，如果 types 中有则新增保存
        for (ContractFileType type : types) {
            VendorGroupRequireFileType entity = list.stream().filter(v -> v.getFileType() == type).findFirst()
                    .orElse(null);
            if (entity == null) {
                entity = new VendorGroupRequireFileType();
                entity.setGroup(getEntity());
                entity.setFileType(type);
                getRequireFileTypeService().save(entity);
            }
        }
        ;
        System.out.println("to delete = " + list.stream().filter(v -> !types.contains(v.getFileType())).toList());
        list.stream().filter(v -> !types.contains(v.getFileType())).forEach(getRequireFileTypeService()::delete);
        // save(entity);
        loadSelectedRoles();
    }

    public VendorGroupRequireFileTypeService getRequireFileTypeService() {
        return getCachedBean(VendorGroupRequireFileTypeService.class);
    }

    public ContractFileService getContractFileService() {
        return getCachedBean(ContractFileService.class);
    }

    public ContractFileTypeService getContractFileTypeService() {
        return getCachedBean(ContractFileTypeService.class);
    }
}
