package com.ecep.contract.controller.project;

import com.ecep.contract.controller.AbstEntityManagerSkin;
import com.ecep.contract.controller.BaseController;
import com.ecep.contract.controller.ComboBoxUtils;
import com.ecep.contract.controller.ManagerSkin;
import com.ecep.contract.controller.table.cell.CompanyTableCell;
import com.ecep.contract.controller.table.cell.ProductTypeTableCell;
import com.ecep.contract.controller.table.cell.ProjectSaleTypeTableCell;
import com.ecep.contract.controller.table.cell.ProjectTypeTableCell;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ProductTypeService;
import com.ecep.contract.service.ProjectSaleTypeService;
import com.ecep.contract.service.ProjectService;
import com.ecep.contract.service.ProjectTypeService;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.vm.ProjectViewModel;
import com.ecep.contract.vo.ProjectVo;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.CurrencyStringConverter;
import lombok.Setter;

public class ProjectManagerSkin
        extends AbstEntityManagerSkin<ProjectVo, ProjectViewModel, ProjectManagerSkin, ProjectManagerWindowController>
        implements ManagerSkin {
    @Setter
    private CompanyService companyService;
    @Setter
    private ProjectTypeService projectTypeService;
    @Setter
    private ProjectSaleTypeService saleTypeService;
    @Setter
    private ProductTypeService productTypeService;

    public ProjectManagerSkin(ProjectManagerWindowController controller) {
        super(controller);
    }

    public ProjectService getProjectService() {
        return controller.getViewModelService();
    }

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

    public ProjectSaleTypeService getSaleTypeService() {
        if (saleTypeService == null) {
            saleTypeService = getBean(ProjectSaleTypeService.class);
        }
        return saleTypeService;
    }

    public ProjectTypeService getProjectTypeService() {
        if (projectTypeService == null) {
            projectTypeService = getBean(ProjectTypeService.class);
        }
        return projectTypeService;
    }

    public ProductTypeService getProductTypeService() {
        if (productTypeService == null) {
            productTypeService = getBean(ProductTypeService.class);
        }
        return productTypeService;
    }

    @Override
    public ParamUtils.Builder getSpecification() {
        ParamUtils.Builder params = super.getSpecification();
        if (controller.saleTypeSelector.getValue() != null) {
            params.equals("saleType", controller.saleTypeSelector.getValue());
        }
        return params;
    }

    @Override
    public void initializeTable() {
        ComboBoxUtils.initialComboBox(controller.saleTypeSelector, getSaleTypeService().findAll(), true);
        controller.saleTypeSelector.valueProperty().addListener((observable, oldValue, newValue) -> {
            loadTableDataSet(false);
        });

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

        controller.amountColumn.setCellValueFactory(param -> param.getValue().getAmount());
        controller.amountColumn
                .setCellFactory(TextFieldTableCell.forTableColumn(new CurrencyStringConverter(getLocale())));// ,
        // "#,##0"

        initializeSaleTypeColumn(controller.saleTypeColumn);
        initializeCustomerColumn(controller.customerColumn);
        initializeProjectTypeColumn(controller.projectTypeColumn);
        initializeProductTypeColumn(controller.productTypeColumn);

        controller.useBidColumn.setCellValueFactory(param -> param.getValue().getUseBid());
        controller.useBidColumn.setCellFactory(CheckBoxTableCell.forTableColumn(controller.useBidColumn));
        controller.useOfferColumn.setCellValueFactory(param -> param.getValue().getUseOffer());
        controller.useOfferColumn.setCellFactory(CheckBoxTableCell.forTableColumn(controller.useOfferColumn));

        controller.createdColumn.setCellValueFactory(param -> param.getValue().getCreated());

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

    private void initializeCustomerColumn(TableColumn<ProjectViewModel, Integer> column) {
        column.setCellValueFactory(param -> param.getValue().getCustomer());
        column.setCellFactory(param -> new CompanyTableCell<>(getCompanyService()));
    }

    private void initializeProductTypeColumn(TableColumn<ProjectViewModel, Integer> column) {
        column.setCellValueFactory(param -> param.getValue().getProductType());
        column.setCellFactory(param -> new ProductTypeTableCell<>(getProductTypeService()));
    }

    private void initializeProjectTypeColumn(TableColumn<ProjectViewModel, Integer> column) {
        column.setCellValueFactory(param -> param.getValue().getProjectType());
        column.setCellFactory(param -> new ProjectTypeTableCell<>(getProjectTypeService()));
    }

    private void initializeSaleTypeColumn(TableColumn<ProjectViewModel, Integer> column) {
        column.setCellValueFactory(param -> param.getValue().getSaleType());
        column.setCellFactory(param -> new ProjectSaleTypeTableCell<>(getSaleTypeService()));
    }

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

    @Override
    protected void onTableCreateNewAction(ActionEvent event) {
        BaseController.show(ApplyNewProjectWindowController.class, getTableView().getScene().getWindow(),
                controller -> {
                    controller.setOnApplied(project -> {
                        ProjectViewModel viewModel = ProjectViewModel.from(project);
                        dataSet.addFirst(viewModel);
                        showInOwner(viewModel);
                    });
                });
    }

    private void showInOwner(ProjectViewModel model) {
        showInOwner(ProjectWindowController.class, model);
    }
}
