package com.ecep.contract.controller.vendor;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ecep.contract.util.ProxyUtils;

import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.controller.AbstEntityManagerSkin;
import com.ecep.contract.controller.ComboBoxUtils;
import com.ecep.contract.controller.table.cell.CompanyTableCell;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.VendorCatalog;
import com.ecep.contract.model.VendorTypeLocal;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.vm.CompanyVendorViewModel;

import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
import lombok.Setter;

public class CompanyVendorManagerSkin
        extends
        AbstEntityManagerSkin<CompanyVendor, CompanyVendorViewModel, CompanyVendorManagerSkin, CompanyVendorManagerWindowController> {

    @Setter
    private CompanyService companyService;
    @Setter
    private CompanyVendorService companyVendorService;

    public CompanyVendorManagerSkin(CompanyVendorManagerWindowController controller) {
        super(controller);
    }

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

    public CompanyVendorService getCompanyVendorService() {
        if (companyVendorService == null) {
            companyVendorService = getBean(CompanyVendorService.class);
        }
        return companyVendorService;
    }

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

    @Override
    public void initializeTable() {

        List<VendorTypeLocal> vendorTypeLocals = getCompanyVendorService()
                .findAllTypes(controller.getLocale());
        ComboBoxUtils.initialComboBox(controller.typeSelector, vendorTypeLocals, true);
        controller.typeSelector.valueProperty().addListener((observable, oldValue, newValue) -> {
            loadTableDataSet(true);
        });

        controller.idColumn.setCellValueFactory(param -> param.getValue().getId());
        controller.codeColumn.setCellValueFactory(param -> param.getValue().getCode());

        Map<Integer, VendorCatalog> vendorClassMap = getCompanyVendorService().findAllCatalogs().stream()
                .collect(Collectors.toMap(VendorCatalog::getId, v -> v));

        controller.catalogColumn.setCellValueFactory(param -> Bindings.createStringBinding(() -> {
            SimpleObjectProperty<VendorCatalog> catalog = param.getValue().getCatalog();
            VendorCatalog vendorCatalog = catalog.get();
            if (vendorCatalog == null) {
                return "-";
            } else {
                if (!ProxyUtils.isInitialized(vendorCatalog)) {
                    vendorCatalog = vendorClassMap.get(vendorCatalog.getId());
                    if (vendorCatalog == null) {
                        vendorCatalog = getCompanyVendorService().findCatalogById(catalog.get().getId());
                        if (vendorCatalog != null) {
                            vendorClassMap.put(vendorCatalog.getId(), vendorCatalog);
                        } else {
                            return "#" + catalog.get().getId();
                        }
                    }
                    catalog.set(vendorCatalog);
                }
                return vendorCatalog.getName();
            }
        }, param.getValue().getCatalog()));

        controller.typeColumn.setCellValueFactory(param -> param.getValue().getType().map(type -> {
            VendorTypeLocal local = vendorTypeLocals.stream().filter(v -> v.getType() == type).findFirst().orElse(null);
            if (local == null) {
                return type.name();
            } else {
                return local.getValue();
            }
        }));

        controller.purchaseColumn.setCellValueFactory(param -> param.getValue().getPurchase());
        controller.companyColumn.setCellValueFactory(param -> param.getValue().getCompany());
        controller.companyColumn.setCellFactory(param -> new CompanyTableCell<>(getCompanyService()));

        controller.developDateColumn.setCellValueFactory(param -> param.getValue().getDevelopDate());
        controller.pathColumn.setCellValueFactory(param -> param.getValue().getPath());
        controller.createdColumn
                .setCellValueFactory(param -> param.getValue().getCreated().map(MyDateTimeUtils::format));

        Platform.runLater(() -> {
            getTableView().getSortOrder().add(controller.idColumn);
        });
    }

    @Override
    protected void onTableRowDoubleClickedAction(CompanyVendorViewModel item) {
        showInOwner(item);
    }

    private void showInOwner(CompanyVendorViewModel model) {
        showInOwner(CompanyVendorWindowController.class, model);
    }
}