package com.ecep.contract.controller.contract;

import java.io.File;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.ecep.contract.DesktopUtils;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.tab.ContractTabSkinBase;
import com.ecep.contract.controller.tab.ContractTabSkinFiles;
import com.ecep.contract.controller.tab.ContractTabSkinItemsV2;
import com.ecep.contract.controller.tab.ContractTabSkinPayPlan;
import com.ecep.contract.controller.tab.ContractTabSkinPurchaseOrders;
import com.ecep.contract.controller.tab.ContractTabSkinSaleOrders;
import com.ecep.contract.controller.tab.ContractTabSkinSubContract;
import com.ecep.contract.controller.tab.ContractTabSkinVendorBid;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.Contract;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ContractService;
import com.ecep.contract.task.ContractRepairTask;
import com.ecep.contract.task.ContractVerifyTasker;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.ContractViewModel;

import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Window;
import javafx.stage.WindowEvent;

@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/contract/contract.fxml")
public class ContractWindowController
        extends AbstEntityController<Contract, ContractViewModel> {

    public static void show(Contract contract, Window owner) {
        ContractViewModel model = new ContractViewModel();
        model.update(contract);
        show(model, owner);
    }

    /**
     * 显示界面
     */
    public static void show(ContractViewModel viewModel, Window window) {
        show(ContractWindowController.class, viewModel, window);
    }

    public BorderPane root;
    public Tab baseInfoTab;
    public Tab extendVendorInfo;
    public Tab contractTab;
    public Tab bidVendorTab;
    public Tab payPlanTab;
    public Tab itemTab;
    public Tab fileTab;

    public Button verifyBtn;
    public Button openRelativeCompanyCustomerBtn;
    public Button openRelativeCompanyVendorBtn;

    public TextField nameField;
    public TextField guidField;
    public TextField codeField;
    public TextField parentCodeField;
    public TextField companyField;
    public TextField stateField;
    public TextField groupField;
    public TextField typeField;
    public TextField kindField;
    public TextField pathField;
    public DatePicker orderDateField;
    public DatePicker startDateField;
    public DatePicker endDateField;
    public TextField setupPersonField;
    public DatePicker setupDateField;
    public TextField inurePersonField;
    public DatePicker inureDateField;
    public TextField varyPersonField;
    public DatePicker varyDateField;
    public TextField projectField;
    public TextField employeeField;
    public TextField handlerField;
    public TextField createdField;
    public TextArea descriptionField;
    public TextField amountField;
    public TextField totalQuantityField;
    public TextField totalAmountField;
    public TextField totalUnTaxAmountField;
    public TextField execQuantityField;
    public TextField execAmountField;
    public TextField execUnTaxAmountField;
    public TextField payWayField;
    public Button linkContractProjectBtn;

    public Button contractRenameBtn;
    public Button contractPathCreateBtn;
    public Button contractPathChangeBtn;
    public Button contractPathAsNameBtn;
    public Button contractPathAsCodeBtn;
    /**
     * 打开主合同
     */
    public Button openMainContractBtn;
    /**
     * 计算主合同编号按钮
     */
    public Button calcMainContractNoBtn;
    public Label versionLabel;

    @Override
    public ContractService getViewModelService() {
        return getCachedBean(ContractService.class);
    }

    public CompanyService getCompanyService() {
        return getCachedBean(CompanyService.class);
    }

    public void onShown(WindowEvent windowEvent) {
        super.onShown(windowEvent);
        getTitle().bind(viewModel.getName()
                .map(name -> "[" + viewModel.getId().get() + "] " + viewModel.getCode().get() + " " + name + " 合同详情"));
        root.getScene().getStylesheets().add("/ui/contract/contract.css");
    }

    @Override
    protected void registerTabSkins() {
        TabPane tabPane = baseInfoTab.getTabPane();
        ObservableList<Tab> tabs = tabPane.getTabs();

        registerTabSkin(baseInfoTab, tab -> new ContractTabSkinBase(this));
        switch (viewModel.getPayWay().get()) {
            case RECEIVE -> {
                tabs.remove(extendVendorInfo);
                registerTabSkin(contractTab, t -> new ContractTabSkinSubContract(this));
                tabs.remove(bidVendorTab);
                Tab saleOrderTab = new Tab("销售订单");
                tabs.add(saleOrderTab);
                registerTabSkin(saleOrderTab, tab -> new ContractTabSkinSaleOrders(this, tab));
                tabs.add(new Tab("票据"));
                break;
            }
            case PAY -> {
                registerTabSkin(extendVendorInfo, t -> new ContractTabSkinExtendVendorInfo(this));
                tabs.remove(contractTab);
                registerTabSkin(bidVendorTab, t -> new ContractTabSkinVendorBid(this));

                Tab purchaseOrderTab = new Tab("采购订单");
                tabs.add(purchaseOrderTab);
                registerTabSkin(purchaseOrderTab, tab -> new ContractTabSkinPurchaseOrders(this, tab));

                tabs.add(new Tab("发货单"));
                tabs.add(new Tab("签收单"));
                tabs.add(new Tab("付款单"));
                break;
            }
        }

        registerTabSkin(itemTab, tab -> new ContractTabSkinItemsV2(this));
        registerTabSkin(payPlanTab, tab -> new ContractTabSkinPayPlan(this));
        registerTabSkin(fileTab, tab -> new ContractTabSkinFiles(this));
    }

    public void onContractOpenInExplorerAction(ActionEvent event) {
        Contract contract = getEntity();
        String path = contract.getPath();
        if (!StringUtils.hasText(path)) {
            setStatus("未设置目录");
            return;
        }
        File file = new File(path);
        if (!file.exists()) {
            setStatus("目录错误,不存在");
            return;
        }
        DesktopUtils.showInExplorer(file);
    }

    public void onContractOpenRelativeCompanyAction(ActionEvent event) {
        Contract contract = getEntity();
        if (contract.getCompany() == null) {
            UITools.showAlertAndWait("没有关联的公司，你可以尝试同步修复异常。");
            return;
        }
        Integer companyId = contract.getCompany().getId();
        Company company = getCompanyService().findById(companyId);
        if (company != null) {
            CompanyWindowController.show(company, root.getScene().getWindow());
        }
    }

    public void onSyncContractAction(ActionEvent event) {
        ContractRepairTask task = new ContractRepairTask();
        task.setContract(getEntity());
        UITools.showTaskDialogAndWait("同步合同", task, null);
        if (task.isRepaired()) {
            setEntity(task.getContract());
        }
        if (task.isFilesUpdated()) {
            ContractTabSkinFiles tabSkin = getTabSkin(ContractTabSkinFiles.class);
            if (tabSkin != null) {
                tabSkin.loadTableDataSet();
            }
        }
        if (task.isPlayPlanUpdated()) {
            ContractTabSkinPayPlan tabSkin = getTabSkin(ContractTabSkinPayPlan.class);
            if (tabSkin != null) {
                tabSkin.loadTableDataSet();
            }
        }
        if (task.isItemsUpdated()) {
            ContractTabSkinItemsV2 tabSkin = getTabSkin(ContractTabSkinItemsV2.class);
            if (tabSkin != null) {
                tabSkin.loadTableDataSet();
            }
        }
        if (task.isSaleOrderUpdated()) {
            ContractTabSkinSaleOrders tabSkin = getTabSkin(ContractTabSkinSaleOrders.class);
            if (tabSkin != null) {
                tabSkin.loadTableDataSet();
            }
        }
    }

    /**
     * 验证合同合规性
     */
    public void onContractVerifyAction(ActionEvent event) {
        Contract contract = getEntity();
        ContractVerifyTasker task = new ContractVerifyTasker();
        task.setContract(contract);
        UITools.showTaskDialogAndWait("同步合规性验证", task, null);
    }
}
