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

import java.util.ArrayList;
import java.util.List;

import com.ecep.contract.VendorType;
import com.ecep.contract.util.ComboBoxUtils;
import com.ecep.contract.controller.table.cell.VendorTypeTableCell;
import com.ecep.contract.service.*;
import com.ecep.contract.vo.*;

import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.controller.table.AbstEntityTableTabSkin;
import com.ecep.contract.controller.table.cell.CompanyVendorTableCell;
import com.ecep.contract.controller.vendor.VendorWindowController;
import com.ecep.contract.util.BooleanConfigProperty;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.IntegerConfigProperty;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.util.ParamUtils.Builder;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CompanyVendorApprovedItemViewModel;
import com.ecep.contract.vm.CompanyVendorApprovedListViewModel;

import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import lombok.Setter;

@FxmlPath("/ui/company/vendor/vendor_approved_list-tab-vendor.fxml")
public class VendorApprovedListTabSkinVendors
        extends
        AbstEntityTableTabSkin<VendorApprovedListWindowController, VendorApprovedVo, CompanyVendorApprovedListViewModel, VendorApprovedItemVo, CompanyVendorApprovedItemViewModel>
        implements TabSkin {
    @Setter
    private VendorApprovedItemService itemService;
    private CompanyService companyService;
    private VendorService vendorService;
    private CompanyOldNameService companyOldNameService;

    public ComboBox<VendorTypeLocalVo> typeSelector;
    public Menu vendorTableContextChangeTypeMenu;

    public TableColumn<CompanyVendorApprovedItemViewModel, Number> idColumn;
    public TableColumn<CompanyVendorApprovedItemViewModel, Integer> vendorColumn;
    public TableColumn<CompanyVendorApprovedItemViewModel, VendorType> typeColumn;
    public TableColumn<CompanyVendorApprovedItemViewModel, String> descriptionColumn;

    public CheckMenuItem logUnqualifiedVendorChecker;
    public CheckMenuItem logTypicallyVendorNoThreeYearContractChecker;
    public CheckMenuItem logUnqualifiedVendorRemoveChecker;
    public CheckMenuItem logTypicallyVendorNoThreeYearContractDetailChecker;
    public Spinner<Integer> qualifiedVendorEveryYearMinContractsSpinner;

    public VendorApprovedListTabSkinVendors(VendorApprovedListWindowController controller) {
        super(controller);
    }

    public CompanyService getCompanyService() {
        if (companyService == null) {
            companyService = getBean(CompanyService.class);
        }
        return companyService;
    }

    public CompanyOldNameService getCompanyOldNameService() {
        if (companyOldNameService == null) {
            companyOldNameService = getBean(CompanyOldNameService.class);
        }
        return companyOldNameService;
    }

    public VendorService getVendorService() {
        if (vendorService == null) {
            vendorService = getBean(VendorService.class);
        }
        return vendorService;
    }

    public SysConfService getConfService() {
        return controller.getConfService();
    }

    VendorApprovedItemService getItemService() {
        if (itemService == null) {
            itemService = getBean(VendorApprovedItemService.class);
        }
        return itemService;
    }

    @Override
    protected VendorApprovedItemService getViewModelService() {
        return getItemService();
    }

    @Override
    public ParamUtils.Builder getSpecification() {
        Builder params = super.getSpecification();
        VendorTypeLocalVo selectorType = typeSelector.getValue();
        if (selectorType != null) {
            params.equals("type", selectorType.getType());
        }
        return params;
    }

    @Override
    public ParamUtils.Builder getSpecification(VendorApprovedVo parent) {
        Builder params = getSpecification();
        params.equals("list", parent.getId());
        return params;
    }

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

    @Override
    public void initializeTab() {

        ComboBoxUtils.initialComboBox(typeSelector, null, getCachedBean(VendorTypeService.class), true);

        idColumn.setCellValueFactory(param -> param.getValue().getId());
        // 厂商, vendor
        vendorColumn.setCellValueFactory(param -> param.getValue().getVendor());
        vendorColumn.setCellFactory(CompanyVendorTableCell.forTableColumn(getVendorService()));
        // 类型, type
        typeColumn.setCellValueFactory(param -> param.getValue().getType());
        typeColumn.setCellFactory(VendorTypeTableCell.forTableColumn(getCachedBean(VendorTypeService.class)));
        // 描述, description
        descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        List<MenuItem> menuItems = new ArrayList<>();
        for (VendorTypeLocalVo value : getCachedBean(VendorTypeService.class).findAll()) {
            MenuItem menuItem = new MenuItem();
            menuItem.setText(value.getValue());
            menuItem.setOnAction(event -> {
                changeVendorTableSelectedItemType(value);
            });
            menuItems.add(menuItem);
        }
        vendorTableContextChangeTypeMenu.getItems().setAll(menuItems);

        SimpleBooleanProperty property = new SimpleBooleanProperty(false) {
            @Override
            protected void invalidated() {
                super.invalidated();
                System.out.println("get() = " + get());
            }
        };

        // TODO bindBidirectional 失效问题
        logUnqualifiedVendorChecker.selectedProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("newValue = " + newValue);
        });

        logUnqualifiedVendorChecker.selectedProperty().bindBidirectional(
                new BooleanConfigProperty("vendor.approved.list.log-unqualified-vendor", getConfService()));

        logUnqualifiedVendorRemoveChecker.selectedProperty().bindBidirectional(
                new BooleanConfigProperty("vendor.approved.list.log-unqualified-vendor-remove", getConfService()));
        logTypicallyVendorNoThreeYearContractChecker.selectedProperty().bindBidirectional(
                new BooleanConfigProperty("vendor.approved.list.log-typically-vendor-no-three-year-contract",
                        getConfService()));
        logTypicallyVendorNoThreeYearContractDetailChecker.selectedProperty().bindBidirectional(
                new BooleanConfigProperty("vendor.approved.list.log-typically-vendor-no-three-year-contract-detail",
                        getConfService()));
        qualifiedVendorEveryYearMinContractsSpinner.setEditable(true);
        qualifiedVendorEveryYearMinContractsSpinner.getValueFactory().valueProperty().bindBidirectional(
                new IntegerConfigProperty("vendor.approved.list.qualified-vendor-every-year-mini-contract",
                        getConfService()).asObject());

        super.initializeTab();
    }

    private void changeVendorTableSelectedItemType(VendorTypeLocalVo value) {
        CompanyVendorApprovedItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
        selectedItem.getType().set(value.getType());

        int id = selectedItem.getId().get();
        VendorApprovedItemService itemService = getItemService();
        VendorApprovedItemVo item = itemService.findById(id);
        if (selectedItem.copyTo(item)) {
            VendorApprovedItemVo saved = itemService.save(item);
            selectedItem.update(saved);
        }
    }

    public void onVendorTableCreateNewAction(ActionEvent event) {

        // 选中一个未添加的供应商

    }

    public void onVendorTableImportAction(ActionEvent event) {
        VendorApprovedVo approvedList = getParent();
        VendorApprovedListVendorImportTask task = new VendorApprovedListVendorImportTask(approvedList);

        task.setLogUnqualifiedVendor(logUnqualifiedVendorChecker.isSelected());
        task.setLogTypicallyVendorNoThreeYearContract(logTypicallyVendorNoThreeYearContractChecker.isSelected());
        task.setLogTypicallyVendorNoThreeYearContractDetail(
                logTypicallyVendorNoThreeYearContractDetailChecker.isSelected());
        task.setLogUnqualifiedVendorRemove(logUnqualifiedVendorRemoveChecker.isSelected());
        task.setEveryYearMinContracts(qualifiedVendorEveryYearMinContractsSpinner.getValue());

        UITools.showTaskDialogAndWait("导入供方", task, null);
    }

    public void onVendorTableRefreshAction(ActionEvent event) {
        loadTableDataSet();
    }

    public void onVendorTableUpdateAction(ActionEvent event) {
        VendorService vendorService = getVendorService();
        CompanyService companyService = getCompanyService();
        CompanyOldNameService companyOldNameService = getCompanyOldNameService();

        ObservableList<CompanyVendorApprovedItemViewModel> selectedItems = getTableView().getSelectionModel()
                .getSelectedItems();
        List<CompanyVendorApprovedItemViewModel> list = new ArrayList<>(selectedItems);
        while (!list.isEmpty()) {
            CompanyVendorApprovedItemViewModel first = list.removeFirst();
            Integer vendorId = first.getVendor().get();
            ;
            VendorVo companyVendor = vendorService.findById(vendorId);
            CompanyVo company = companyService.findById(companyVendor.getCompanyId());
            CompanyOldNameVo oldName = companyOldNameService.findMatchByDate(company,
                    viewModel.getPublishDate().get());
            if (oldName != null) {
                System.out.println("oldName = " + oldName);
            }
        }
    }

    public void onVendorTableShowVendorAction(ActionEvent event) {
        CompanyVendorApprovedItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
        VendorVo companyVendor = getVendorService().findById(selectedItem.getVendor().get());
        VendorWindowController.show(companyVendor, null);
    }

    public void onVendorTableDeleteAction(ActionEvent event) {
        ObservableList<CompanyVendorApprovedItemViewModel> selectedItems = getTableView().getSelectionModel()
                .getSelectedItems();

        List<CompanyVendorApprovedItemViewModel> list = new ArrayList<>(selectedItems);

        while (!list.isEmpty()) {

            CompanyVendorApprovedItemViewModel first = list.removeFirst();
            if (deleteRow(first)) {
                dataSet.remove(first);
            }
        }
    }
}
