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

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

import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils;

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.CompanyVendorWindowController;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyOldName;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorApprovedItem;
import com.ecep.contract.model.CompanyVendorApprovedList;
import com.ecep.contract.model.VendorTypeLocal;
import com.ecep.contract.service.CompanyOldNameService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CompanyVendorApprovedItemService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.service.SysConfService;
import com.ecep.contract.util.BooleanConfigProperty;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.IntegerConfigProperty;
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.FXCollections;
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 javafx.util.StringConverter;
import lombok.Setter;

@FxmlPath("/ui/company/vendor/vendor_approved_list-tab-vendor.fxml")
public class CompanyVendorApprovedListTabSkinVendors
        extends
        AbstEntityTableTabSkin<CompanyVendorApprovedListWindowController, CompanyVendorApprovedList, CompanyVendorApprovedListViewModel, CompanyVendorApprovedItem, CompanyVendorApprovedItemViewModel>
        implements TabSkin {
    @Setter
    private CompanyVendorApprovedItemService itemService;
    private CompanyService companyService;
    private CompanyVendorService companyVendorService;
    private CompanyOldNameService companyOldNameService;

    public ComboBox<VendorTypeLocal> typeSelector;
    public Menu vendorTableContextChangeTypeMenu;

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

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

    public CompanyVendorApprovedListTabSkinVendors(CompanyVendorApprovedListWindowController 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 CompanyVendorService getCompanyVendorService() {
        if (companyVendorService == null) {
            companyVendorService = getBean(CompanyVendorService.class);
        }
        return companyVendorService;
    }

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

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

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

    @Override
    public Map<String, Object> getSpecification() {
        Map<String, Object> params = super.getSpecification();
        VendorTypeLocal selectorType = typeSelector.getValue();
        if (selectorType != null) {
            params.put("type", selectorType.getType());
        }
        return params;
    }

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

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

    @Override
    public void initializeTab() {
        List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService()
                .findAllTypes(controller.getLocale().toLanguageTag());

        ObservableList<VendorTypeLocal> vendorTypeItems = FXCollections.observableArrayList();
        vendorTypeItems.add(null);
        vendorTypeItems.addAll(vendorTypeLocals);
        typeSelector.setItems(vendorTypeItems);
        typeSelector.setConverter(new StringConverter<>() {
            @Override
            public String toString(VendorTypeLocal typeLocal) {
                if (typeLocal == null) {
                    return "";
                }
                return typeLocal.getValue();
            }

            @Override
            public VendorTypeLocal fromString(String string) {
                return null;
            }
        });

        idColumn.setCellValueFactory(param -> param.getValue().getId());
        vendorColumn.setCellValueFactory(param -> param.getValue().getVendor());
        vendorColumn.setCellFactory(param -> new VendorTableCell(getCompanyVendorService(), getCompanyService()));

        typeColumn.setCellValueFactory(param -> param.getValue().getType().map(v -> {
            if (v == null) {
                return "-";
            }
            for (VendorTypeLocal vendorTypeLocal : vendorTypeLocals) {
                if (vendorTypeLocal.getType() == v) {
                    return vendorTypeLocal.getValue();
                }
            }
            return v.name();
        }));

        descriptionColumn.setCellValueFactory(param -> param.getValue().getDescription());
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        List<MenuItem> menuItems = new ArrayList<>();
        for (VendorTypeLocal value : vendorTypeLocals) {
            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(VendorTypeLocal value) {
        CompanyVendorApprovedItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
        selectedItem.getType().set(value.getType());

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

    public void onVendorTableCreateNewAction(ActionEvent event) {

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

    }

    public void onVendorTableImportAction(ActionEvent event) {
        CompanyVendorApprovedList approvedList = getParent();
        CompanyVendorApprovedListVendorImportTask task = new CompanyVendorApprovedListVendorImportTask(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) {
        CompanyVendorService vendorService = getCompanyVendorService();
        CompanyService companyService = getCompanyService();

        ObservableList<CompanyVendorApprovedItemViewModel> selectedItems = getTableView().getSelectionModel()
                .getSelectedItems();
        List<CompanyVendorApprovedItemViewModel> list = new ArrayList<>(selectedItems);
        while (!list.isEmpty()) {
            CompanyVendorApprovedItemViewModel first = list.removeFirst();
            CompanyVendor companyVendor = first.getVendor().get();
            if (!ProxyUtils.isInitialized(companyVendor)) {
                companyVendor = vendorService.findById(companyVendor.getId());
                first.getVendor().set(companyVendor);
            }
            Company company = companyVendor.getCompany();
            if (!ProxyUtils.isInitialized(company)) {
                company = companyService.findById(company.getId());
                companyVendor.setCompany(company);
            }
            CompanyOldName oldName = getCompanyOldNameService().findMatchByDate(company,
                    viewModel.getPublishDate().get());
            if (oldName != null) {
                System.out.println("oldName = " + oldName);
            }
        }
    }

    public void onVendorTableShowVendorAction(ActionEvent event) {
        CompanyVendorApprovedItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
        CompanyVendor companyVendor = selectedItem.getVendor().get();
        if (!ProxyUtils.isInitialized(companyVendor)) {
            companyVendor = getCompanyVendorService().findById(companyVendor.getId());
        }

        CompanyVendorWindowController.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);
            }
        }
    }

    static class VendorTableCell extends CompanyVendorTableCell<CompanyVendorApprovedItemViewModel> {
        public VendorTableCell(CompanyVendorService companyVendorService, CompanyService companyService) {
            super();
            setService(companyVendorService);
            setCompanyService(companyService);
        }

        @Override
        protected boolean isInitialized(CompanyVendor item) {
            CompanyVendorApprovedItemViewModel row = getTableRow().getItem();
            if (StringUtils.hasText(row.getVendorName().get())) {
                return true;
            }
            return super.isInitialized(item);
        }

        @Override
        public String format(CompanyVendor vendor) {
            CompanyVendorApprovedItemViewModel row = getTableRow().getItem();
            if (StringUtils.hasText(row.getVendorName().get())) {
                return row.getVendorName().get();
            }
            return super.format(vendor);
        }
    }
}
