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.InventoryTableCell;
import com.ecep.contract.controller.table.cell.LocalDateTimeTableCell;
import com.ecep.contract.service.ContractItemService;
import com.ecep.contract.service.InventoryService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.vm.ContractItemComposeViewModel;
import com.ecep.contract.vm.ContractItemViewModel;
import com.ecep.contract.vm.InventoryViewModel;
import com.ecep.contract.vo.ContractItemVo;
import com.ecep.contract.vo.InventoryVo;

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.StringConverter;
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<ContractItemVo, ContractItemViewModel>
        implements TabSkin, EditableEntityTableTabSkin<ContractItemVo, 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;
    /**
     * 合同内容, Inventory
     */
    public TableColumn<ContractItemViewModel, Integer> inventoryColumn;
    public TableColumn<ContractItemViewModel, Number> refIdColumn;
    public TableColumn<ContractItemViewModel, String> codeColumn;
    /**
     * 合同内容, 合同创建人, Employee
     */
    public TableColumn<ContractItemViewModel, Integer> creatorColumn;
    public TableColumn<ContractItemViewModel, LocalDateTime> createDateColumn;
    /**
     * 合同内容, 合同更新人, Employee
     */
    public TableColumn<ContractItemViewModel, Integer> 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());
        inventoryColumn.setCellFactory(
                InventoryTableCell.forTableColumn(getInventoryService(), new StringConverter<InventoryVo>() {
                    @Override
                    public String toString(InventoryVo object) {
                        return object != null ? object.getCode() : "";
                    }

                    @Override
                    public InventoryVo fromString(String string) {
                        return getInventoryService().findByCode(string);
                    }
                }));

        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;
    }

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