package com.ecep.contract.controller.tab;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import org.springframework.util.StringUtils;

import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.controller.company.AbstCompanyTableTabSkin;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.company_old_name.CompanyOldNameWindowController;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.service.CompanyOldNameService;
import com.ecep.contract.vm.CompanyOldNameViewModel;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.input.KeyCode;
import lombok.Setter;

/**
 * 曾用名
 */
@FxmlPath("/ui/company/company-tab-oldname.fxml")
public class CompanyTabSkinOldName
        extends AbstCompanyTableTabSkin<CompanyOldName, CompanyOldNameViewModel>
        implements TabSkin {

    /**
     * 以下是曾用名列定义
     */
    public TableColumn<CompanyOldNameViewModel, Number> oldNameTable_idColumn;
    public TableColumn<CompanyOldNameViewModel, String> oldNameTable_nameColumn;
    public TableColumn<CompanyOldNameViewModel, LocalDate> oldNameTable_beginDateColumn;
    public TableColumn<CompanyOldNameViewModel, LocalDate> oldNameTable_endDateColumn;
    public TableColumn<CompanyOldNameViewModel, Boolean> oldNameTable_ambiguityColumn;
    public TableColumn<CompanyOldNameViewModel, String> oldNameTable_pathColumn;
    public TableColumn<CompanyOldNameViewModel, String> oldNameTable_memoColumn;

    public TextField oldNameSearchKeyField;
    public Button oldNameSearchBtn;
    public Button oldNameTable_create_btn;
    public Button oldNameTable_merge_btn;
    public MenuItem oldNameTable_menu_refresh;
    public MenuItem oldNameTable_menu_del;

    @Setter
    private CompanyOldNameService companyOldNameService;

    public CompanyTabSkinOldName(CompanyWindowController controller) {
        super(controller);
    }

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

    @Override
    public Map<String, Object> getSpecification(Company parent) {
        Map<String, Object> params = getSpecification();
        params.put("company", parent.getId());
        return params;
    }

    @Override
    public void initializeTab() {

        oldNameSearchKeyField.setOnKeyReleased(event -> {
            if (event.getCode() == KeyCode.ENTER) {
                oldNameSearchBtn.fire();
            }
        });

        oldNameSearchBtn.setOnAction(this::onTableRefreshAction);

        oldNameTable_create_btn.setOnAction(this::onTableAddAction);
        oldNameTable_merge_btn.setOnAction(this::onTableMergeAction);

        oldNameTable_idColumn.setCellValueFactory(param -> param.getValue().getId());
        oldNameTable_nameColumn.setCellValueFactory(param -> param.getValue().getName());

        oldNameTable_pathColumn.setCellFactory(param -> new FileTableFilePathTableCell());

        oldNameTable_ambiguityColumn.setCellValueFactory(param -> param.getValue().getAmbiguity());
        oldNameTable_ambiguityColumn.setCellFactory(c -> new CheckBoxTableCell<>());

        oldNameTable_beginDateColumn.setCellValueFactory(param -> param.getValue().getBeginDate());
        oldNameTable_endDateColumn.setCellValueFactory(param -> param.getValue().getEndDate());

        oldNameTable_memoColumn.setCellValueFactory(param -> param.getValue().getMemo());

        oldNameTable_menu_refresh.setOnAction(this::onTableRefreshAction);
        oldNameTable_menu_del.setOnAction(this::onTableDeleteAction);

        super.initializeTab();
    }

    @Override
    protected void onTableAddAction(ActionEvent event) {
        //
        TextInputDialog dialog = new TextInputDialog();
        dialog.setHeaderText("请输入曾用名");
        dialog.setTitle("新建曾用名");
        Optional<String> optional = dialog.showAndWait();
        if (optional.isEmpty()) {
            return;
        }
        CompanyOldName oldName = new CompanyOldName();
        oldName.setName(optional.get());
        oldName.setCompanyId(viewModel.getId().get());
        oldName.setAmbiguity(true);
        getViewModelService().save(oldName);
        loadTableDataSet();
    }

    @Override
    protected boolean deleteRow(CompanyOldNameViewModel row) {
        CompanyOldName entity = getViewModelService().findById(row.getId().get());
        if (entity != null) {
            getViewModelService().delete(entity);
        }
        return true;
    }

    private void onTableMergeAction(ActionEvent event) {
        Company updater = getParent();
        HashSet<String> nameSet = new HashSet<>();
        nameSet.add(updater.getName());

        List<CompanyOldNameViewModel> removes = new ArrayList<>();
        for (CompanyOldNameViewModel viewModel : dataSet) {

            if (!nameSet.add(viewModel.getName().get())) {
                // fixed 曾用名中有重复时，删除重复的
                deleteRow(viewModel);
                removes.add(viewModel);
            }
        }
        if (!removes.isEmpty()) {
            Platform.runLater(() -> {
                dataSet.removeAll(removes);
            });
            setStatus("移除重复的曾用名" + removes.size());
        }

        int size = nameSet.size();
        int count = 1;
        int merge = 0;
        for (String name : nameSet) {
            controller.setRightStatus(count + "/" + size);
            if (StringUtils.hasText(name)) {
                List<Company> list = getParentService().findAllByName(name);
                for (Company company : list) {
                    // fixed 曾用名中有可能有 updater 的名字,会导致自己删除自己
                    if (Objects.equals(company.getId(), updater.getId())) {
                        continue;
                    }
                    try {
                        getCompanyService().merge(company, updater);
                        setStatus("并户 " + company.getName() + "[" + company.getId() + "] 到当前公司");
                        merge++;
                    } catch (Exception e) {
                        throw new RuntimeException("合并 " + company.getName() + " -> " + updater.getName() + " 失败", e);
                    }
                }
            }
            count++;
        }
        if (merge == 0) {
            setStatus("没有需要并户的公司");
        }
        controller.setRightStatus("");
    }

    @Override
    protected void onTableRowDoubleClickedAction(CompanyOldNameViewModel item) {
        CompanyOldNameWindowController.show(item, controller.root.getScene().getWindow());
    }

    class FileTableFilePathTableCell extends TableCell<CompanyOldNameViewModel, String> {
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty || item == null) {
                setText("");
                return;
            }
            String path = viewModel.getPath().get();
            if (StringUtils.hasText(path)) {
                if (item.startsWith(path)) {
                    item = "~" + item.substring(path.length());
                }
            }
            setText(item);
        }
    }

    protected CompanyOldNameService getViewModelService() {
        if (companyOldNameService == null) {
            companyOldNameService = getBean(CompanyOldNameService.class);
        }
        return companyOldNameService;
    }
}
