package com.ecep.contract.controller.permission;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ecep.contract.controller.ManagerSkin;
import com.ecep.contract.controller.table.TableTabSkin;
import com.ecep.contract.model.Permission;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.FunctionViewModel;
import com.ecep.contract.vm.PermissionViewModel;

import javafx.application.Platform;
import javafx.beans.property.Property;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import lombok.Setter;

public class PermissionManagerSkin implements ManagerSkin, TableTabSkin<Permission, PermissionViewModel> {
    private static final Logger logger = LoggerFactory.getLogger(PermissionManagerSkin.class);
    EmployeeFunctionsManagerWindowController controller;

    @Setter
    private FunctionViewModel viewModel;
    @Setter
    protected TableView<PermissionViewModel> table;
    private final ObservableList<PermissionViewModel> dataSet = FXCollections.observableArrayList();

    public PermissionManagerSkin(EmployeeFunctionsManagerWindowController controller) {
        this.controller = controller;
    }

    @Override
    public void handleException(String message, Throwable ex) {
        if (controller != null) {
            controller.handleException(message, ex);
            return;
        }
        if (logger.isErrorEnabled()) {
            logger.error(message, ex);
        }
        UITools.showExceptionAndWait(message, ex);
    }

    @Override
    public TableView<PermissionViewModel> getTableView() {
        return table;
    }

    @Override
    public void install() {
        initializeTable();
        table.setItems(dataSet);
        loadTableDataSet();
    }

    @Override
    public void initializeTable() {
        table.setEditable(true);

        // controller.permissionTable_descriptionColumn.setCellValueFactory(param ->
        // param.getValue().getDescription());
        // controller.permissionTable_descriptionColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        // controller.permissionTable_descriptionColumn.setOnEditCommit(this::onSignMethodTableDescriptionColumnEditCommitAction);

        table.setItems(dataSet);

        if (table.contextMenuProperty().get() == null) {
            ContextMenu contextMenu = new ContextMenu();
            createContextMenu(contextMenu);
            table.setContextMenu(contextMenu);
        }

    }

    protected void createContextMenu(ContextMenu contextMenu) {
        MenuItem item1 = new MenuItem("新建");
        item1.setOnAction(this::onTableCreateNewAction);

        MenuItem item2 = new MenuItem("刷新");
        item2.setOnAction(this::onTableRefreshAction);

        MenuItem item3 = new MenuItem("删除");
        item3.setOnAction(this::onTableDeleteAction);

        contextMenu.getItems().addAll(item1, item2, item3);
    }

    protected void onTableCreateNewAction(ActionEvent event) {
        Permission newRow = new Permission();
        com.ecep.contract.model.Function function = controller.functionService.findById(viewModel.getId().get());
        newRow.setFunction(function);

        Permission saved = controller.permissionService.save(newRow);
        PermissionViewModel row = PermissionViewModel.from(saved);
        dataSet.add(row);
    }

    protected void onTableRefreshAction(ActionEvent event) {
        loadTableDataSet();
    }

    protected void onTableDeleteAction(ActionEvent event) {
        ObservableList<PermissionViewModel> selectedItems = table.getSelectionModel().getSelectedItems();
        if (selectedItems.isEmpty()) {
            return;
        }
        if (!UITools.showConfirmDialog("删除行", "确认删除选中的" + selectedItems.size() + "条数据？")) {
            return;
        }
        for (PermissionViewModel selectedItem : new ArrayList<>(selectedItems)) {
            if (deleteRow(selectedItem)) {
                dataSet.remove(selectedItem);
            }
        }
    }

    protected boolean deleteRow(PermissionViewModel row) {
        throw new UnsupportedOperationException("未实现");
    }

    private void onNameColumnEditCommitAction(TableColumn.CellEditEvent<PermissionViewModel, String> event) {
        acceptSignMethodCellEditEvent(event, PermissionViewModel::getName);
    }

    private void onKeyColumnEditCommitAction(TableColumn.CellEditEvent<PermissionViewModel, String> event) {
        acceptSignMethodCellEditEvent(event, PermissionViewModel::getKey);
    }

    protected List<PermissionViewModel> loadTableData() {
        if (viewModel == null) {
            return List.of();
        }
        return controller.permissionService.findByFunctionId(viewModel.getId().get()).stream()
                .map(PermissionViewModel::from).toList();
    }

    public void loadTableDataSet() {
        Platform.runLater(() -> {
            dataSet.clear();
            CompletableFuture.runAsync(() -> {
                List<PermissionViewModel> models = loadTableData();
                Platform.runLater(() -> {
                    try {
                        dataSet.setAll(models);
                    } catch (Exception e) {
                        handleException(e);
                    }
                });
            }).exceptionally(this::handleException);
        });
    }

    @Override
    public Map<String, Object> getSpecification() {
        Map<String, Object> params = new HashMap<>();
        // 使用permissionService的specification逻辑
        return params;
    }

    private <K> void acceptSignMethodCellEditEvent(TableColumn.CellEditEvent<PermissionViewModel, K> event,
            Function<PermissionViewModel, Property<K>> function) {
        PermissionViewModel row = event.getRowValue();
        Property<K> property = function.apply(row);
        property.setValue(event.getNewValue());
        try {
            save(row);
        } catch (Exception e) {
            UITools.showExceptionAndWait("保存出错", e);
        }
    }

    protected void save(PermissionViewModel row) {
        int id = row.getId().get();
        Permission type = controller.permissionService.findById(id);
        if (row.copyTo(type)) {
            Permission saved = controller.permissionService.save(type);
            row.update(saved);
        }
    }

}
