package com.ecep.contract.controller.tab;

import java.text.NumberFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;

import com.ecep.contract.controller.contract.AbstContractTableTabSkin;
import com.ecep.contract.controller.contract.ContractWindowController;
import com.ecep.contract.controller.inventory.InventoryWindowController;
import com.ecep.contract.controller.table.EditableEntityTableTabSkin;
import com.ecep.contract.controller.table.cell.EmployeeTableCell;
import com.ecep.contract.controller.table.cell.LocalDateTimeTableCell;
import com.ecep.contract.converter.EntityStringConverter;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractItem;
import com.ecep.contract.model.Employee;
import com.ecep.contract.model.Inventory;
import com.ecep.contract.service.ContractItemService;
import com.ecep.contract.service.InventoryService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ProxyUtils;
import com.ecep.contract.vm.ContractItemComposeViewModel;
import com.ecep.contract.vm.ContractItemViewModel;
import com.ecep.contract.vm.InventoryViewModel;

import javafx.application.Platform;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.converter.CurrencyStringConverter;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;

@FxmlPath("/ui/contract/contract-tab-item-v2.fxml")
public class ContractTabSkinItemsV2
        extends AbstContractTableTabSkin<ContractItem, ContractItemViewModel>
        implements TabSkin, EditableEntityTableTabSkin<ContractItem, ContractItemViewModel> {


    @Setter
    ContractItemService itemService;
    @Setter
    InventoryService inventoryService;

    /*        以下是合同内容          */
    public TableColumn<ContractItemViewModel, Number> idColumn;
    public TableColumn<ContractItemViewModel, String> titleColumn;
    public TableColumn<ContractItemViewModel, String> specificationColumn;
    public TableColumn<ContractItemViewModel, String> unitColumn;

    public TableColumn<ContractItemViewModel, Inventory> inventoryColumn;
    public TableColumn<ContractItemViewModel, Number> refIdColumn;
    public TableColumn<ContractItemViewModel, String> codeColumn;
    public TableColumn<ContractItemViewModel, Employee> creatorColumn;
    public TableColumn<ContractItemViewModel, LocalDateTime> createDateColumn;
    public TableColumn<ContractItemViewModel, Employee> updaterColumn;
    public TableColumn<ContractItemViewModel, LocalDateTime> updateDateColumn;

    public TableColumn<ContractItemViewModel, LocalDate> startDateColumn;
    public TableColumn<ContractItemViewModel, LocalDate> endDateColumn;

    public TableColumn<ContractItemViewModel, Number> exclusiveTaxPriceColumn;
    public TableColumn<ContractItemViewModel, Number> taxRateColumn;
    public TableColumn<ContractItemViewModel, Number> taxPriceColumn;
    public TableColumn<ContractItemViewModel, Number> quantityColumn;
    public TableColumn<ContractItemViewModel, Number> exclusiveTaxAmountColumn;
    public TableColumn<ContractItemViewModel, Number> taxAmountColumn;

    public TableColumn<ContractItemViewModel, String> remarkColumn;

    public ContractTabSkinItemsV2(ContractWindowController controller) {
        super(controller);
    }

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

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

    @Override
    public void initializeTable() {
        super.initializeTable();
        NumberFormat numberInstance = NumberFormat.getNumberInstance(getLocale());
        numberInstance.setMaximumFractionDigits(2);
        numberInstance.setMinimumFractionDigits(2);
        CurrencyStringConverter currencyStringConverter = new CurrencyStringConverter(numberInstance);

        idColumn.setCellValueFactory(param -> param.getValue().getId());
        titleColumn.setCellValueFactory(param -> param.getValue().getTitle());
        specificationColumn.setCellValueFactory(param -> param.getValue().getSpecification());
        unitColumn.setCellValueFactory(param -> param.getValue().getUnit());

        inventoryColumn.setCellValueFactory(param -> param.getValue().getInventory());
        EntityStringConverter<Inventory> converter = new EntityStringConverter<>();
        converter.setInitialized(v -> getInventoryService().findById(v.getId()));
        converter.setFormater(Inventory::getCode);
        inventoryColumn.setCellFactory(TextFieldTableCell.forTableColumn(converter));


        exclusiveTaxPriceColumn.setCellValueFactory(param -> param.getValue().getExclusiveTaxPrice());
        exclusiveTaxPriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));

        taxRateColumn.setCellValueFactory(param -> param.getValue().getTaxRate());
        taxRateColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));

        taxPriceColumn.setCellValueFactory(param -> param.getValue().getTaxPrice());
        taxPriceColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));

        quantityColumn.setCellValueFactory(param -> param.getValue().getQuantity());
        quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter(getLocale())));

        taxAmountColumn.setCellValueFactory(param -> param.getValue().getTaxAmount());
        taxAmountColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));

        exclusiveTaxAmountColumn.setCellValueFactory(param -> param.getValue().getExclusiveTaxAmount());
        exclusiveTaxAmountColumn.setCellFactory(TextFieldTableCell.forTableColumn(currencyStringConverter));

        refIdColumn.setCellValueFactory(param -> param.getValue().getRefId());
        codeColumn.setCellValueFactory(param -> param.getValue().getCode());

        startDateColumn.setCellValueFactory(param -> param.getValue().getStartDate());
        endDateColumn.setCellValueFactory(param -> param.getValue().getEndDate());

        creatorColumn.setCellValueFactory(param -> param.getValue().getCreator());
        creatorColumn.setCellFactory(cell -> new EmployeeTableCell<>(getEmployeeService()));
        updaterColumn.setCellValueFactory(param -> param.getValue().getUpdater());
        updaterColumn.setCellFactory(cell -> new EmployeeTableCell<>(getEmployeeService()));
        createDateColumn.setCellValueFactory(param -> param.getValue().getCreateDate());
        createDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());
        updateDateColumn.setCellValueFactory(param -> param.getValue().getUpdateDate());
        updateDateColumn.setCellFactory(param -> new LocalDateTimeTableCell<>());

        remarkColumn.setCellValueFactory(param -> param.getValue().getRemark());
    }

    public ContractItemService getItemService() {
        if (itemService == null) {
            itemService = getBean(ContractItemService.class);
        }
        return itemService;
    }
    InventoryService getInventoryService() {
        if (inventoryService == null) {
            inventoryService = getBean(InventoryService.class);
        }
        return inventoryService;
    }
    private void sum(ContractItemComposeViewModel model, Contract contract, HashMap<String, ContractItemComposeViewModel> map) {
        double inQuantity = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getQuantity().get()).sum();
        Platform.runLater(() -> model.getIn().getQuantity().set(inQuantity));

        double inTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getTaxAmount().get()).sum();
        Platform.runLater(() -> model.getIn().getTaxAmount().set(inTaxAmount));

        double inExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getIn).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
        Platform.runLater(() -> model.getIn().getExclusiveTaxAmount().set(inExclusiveTaxAmount));

        double outQuantity = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getQuantity().get()).sum();
        Platform.runLater(() -> model.getOut().getQuantity().set(outQuantity));

        double outTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getTaxAmount().get()).sum();
        Platform.runLater(() -> model.getOut().getTaxAmount().set(outTaxAmount));

        double outExclusiveTaxAmount = map.values().stream().map(ContractItemComposeViewModel::getOut).mapToDouble(v -> v.getExclusiveTaxAmount().get()).sum();
        Platform.runLater(() -> model.getOut().getExclusiveTaxAmount().set(outExclusiveTaxAmount));
    }

    @Override
    protected void createContextMenu(ContextMenu contextMenu) {
        super.createContextMenu(contextMenu);
        MenuItem showInventory = new MenuItem("查看存货");
        showInventory.setOnAction(event -> {
            ContractItemViewModel selectedItem = getTableView().getSelectionModel().getSelectedItem();
            Inventory inventory = selectedItem.getInventory().get();
            if (inventory == null) {
                return;
            }
            if (!ProxyUtils.isInitialized(inventory)) {
                inventory = getInventoryService().findById(inventory.getId());
            }
            showInOwner(InventoryWindowController.class, InventoryViewModel.from(inventory));
        });
    }
}
