package com.ecep.contract.controller.contract;

import java.util.List;
import java.util.concurrent.CompletableFuture;

import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.ComboBoxUtils;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ExtendVendorInfo;
import com.ecep.contract.model.VendorGroup;
import com.ecep.contract.service.ExtendVendorInfoService;
import com.ecep.contract.service.VendorGroupService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ProxyUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ExtendVendorInfoViewModel;

import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.util.converter.NumberStringConverter;
import lombok.Setter;

@FxmlPath("/ui/contract/contract-tab-ext-vendor-info.fxml")
public class ContractTabSkinExtendVendorInfo
        extends AbstContractBasedTabSkin {

    @Setter
    private ExtendVendorInfoService extendVendorInfoService;
    @Setter
    private VendorGroupService vendorGroupService;

    @FXML
    public ComboBox<VendorGroup> vendorGroupField;
    @FXML
    public Label vendorGroupLabel;
    @FXML
    public TextField sequenceNumberField;
    @FXML
    public CheckBox assignedProviderField;
    @FXML
    public CheckBox prePurchaseField;

    CompletableFuture<ExtendVendorInfo> loadedFuture;
    private ExtendVendorInfoViewModel viewModel = new ExtendVendorInfoViewModel();

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

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

    @Override
    public void initializeUIComponents() {
        super.initializeUIComponents();
        listenTabSelectionChanged();
    }

    @Override
    public BooleanProperty changeProperty() {
        return viewModel.getChanged();
    }

    @Override
    public void onTabShown() {
        if (loadedFuture == null) {
            loadedFuture = CompletableFuture.supplyAsync(() -> {
                initializeTab();
                Contract contract = getEntity();
                return loadExtendVendorInfo(contract);
            });
        }
    }

    void updateViewModel(ExtendVendorInfo info) {
        if (Platform.isFxApplicationThread()) {
            viewModel.update(info);
        } else {
            Platform.runLater(() -> viewModel.update(info));
        }
    }

    private ExtendVendorInfo loadExtendVendorInfo(Contract contract) {
        ExtendVendorInfoService service = getExtendVendorInfoService();
        try {
            ExtendVendorInfo info = service.findByContract(contract);
            if (info == null) {
                info = service.newInstanceByContract(contract);
                info = service.save(info);
            }
            updateViewModel(info);
            viewModel.bindListener();
            return info;
        } catch (Exception e) {
            UITools.showExceptionAndWait("加载成本时发生错误", e);
            throw e;
        }
    }

    @Override
    public void initializeTab() {
        List<VendorGroup> groups = getVendorGroupService().findAll();
        ComboBoxUtils.initialComboBox(vendorGroupField, groups, true);
        vendorGroupField.valueProperty().bindBidirectional(viewModel.getGroup());
        vendorGroupLabel.textProperty().bind(vendorGroupField.valueProperty().map(v -> {
            if (v == null) {
                return "-";
            }
            if (!ProxyUtils.isInitialized(v)) {
                v = getVendorGroupService().findById(v.getId());
                viewModel.getGroup().set(v);
            }
            return v.getDescription();
        }));

        sequenceNumberField.textProperty().bindBidirectional(viewModel.getCodeSequenceNumber(),
                new NumberStringConverter());
        assignedProviderField.selectedProperty().bindBidirectional(viewModel.getAssignedProvider());
        assignedProviderField.disableProperty().bind(Bindings.createBooleanBinding(() -> {
            VendorGroup group = viewModel.getGroup().get();
            if (group == null) {
                return false;
            }
            return !group.isPriceComparison();
        }, viewModel.getGroup()));

        prePurchaseField.selectedProperty().bindBidirectional(viewModel.getPrePurchase());
    }

    @Override
    public void save() {
        if (loadedFuture != null) {
            ExtendVendorInfo vendorInfo = loadedFuture.join();
            if (viewModel.copyTo(vendorInfo)) {
                ExtendVendorInfo saved = getExtendVendorInfoService().save(vendorInfo);
                updateViewModel(saved);
                loadedFuture = CompletableFuture.completedFuture(saved);
            }
        }
    }

    public ExtendVendorInfoService getExtendVendorInfoService() {
        if (extendVendorInfoService == null) {
            extendVendorInfoService = SpringApp.getBean(ExtendVendorInfoService.class);
        }
        return extendVendorInfoService;
    }

    public VendorGroupService getVendorGroupService() {
        if (vendorGroupService == null) {
            vendorGroupService = SpringApp.getBean(VendorGroupService.class);
        }
        return vendorGroupService;
    }
}
