package com.ecep.contract.controller.company;

import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.SpringApp;
import com.ecep.contract.controller.AbstEntityController;
import com.ecep.contract.controller.customer.CompanyCustomerWindowController;
import com.ecep.contract.controller.tab.AbstEntityBasedTabSkin;
import com.ecep.contract.controller.tab.CompanyTabSkinBankAccount;
import com.ecep.contract.controller.tab.CompanyTabSkinBase;
import com.ecep.contract.controller.tab.CompanyTabSkinBlackReason;
import com.ecep.contract.controller.tab.CompanyTabSkinContact;
import com.ecep.contract.controller.tab.CompanyTabSkinContract;
import com.ecep.contract.controller.tab.CompanyTabSkinFile;
import com.ecep.contract.controller.tab.CompanyTabSkinInvoice;
import com.ecep.contract.controller.tab.CompanyTabSkinOldName;
import com.ecep.contract.controller.tab.CompanyTabSkinOther;
import com.ecep.contract.controller.tab.CompanyTabSkinPurchaseBillVoucher;
import com.ecep.contract.controller.vendor.CompanyVendorWindowController;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.service.CompanyCustomerService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.CompanyVendorService;
import com.ecep.contract.task.CompanyCompositeUpdateTasker;
import com.ecep.contract.task.CompanyVerifyTasker;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.ProxyUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.CompanyViewModel;

import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
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.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.stage.Window;

@Lazy
@Scope("prototype")
@Component
@FxmlPath("/ui/company/company.fxml")
public class CompanyWindowController
        extends AbstEntityController<Company, CompanyViewModel> {
    private static final Logger logger = LoggerFactory.getLogger(CompanyWindowController.class);

    public static void show(Company company, Window window) {
        CompanyViewModel viewModel = new CompanyViewModel();
        if (!ProxyUtils.isInitialized(company)) {
            company = SpringApp.getBean(CompanyService.class).findById(company.getId());
        }
        viewModel.update(company);
        show(viewModel, window);
    }

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

    @Autowired
    private CompanyService companyService;
    @Autowired
    private CompanyCustomerService companyCustomerService;
    @Autowired
    private CompanyVendorService companyVendorService;

    public BorderPane root;
    public TabPane tabPane;
    public Tab baseInfoTab;
    public Tab oldNameTab;
    public Tab contactTab;
    public Tab blackReasonTab;
    public Tab customerTab;
    public Tab vendorTab;
    public Tab bankAccountTab;
    public Tab contractTab;
    public Tab fileTab;
    public Tab invoiceTab;
    public Tab purchaseBillVoucherTab;
    public Tab otherTab;
    /*
    
     */
    public TextField nameField;
    public TextField shortNameField;
    public TextField uidField;
    public TextField entStatusField;
    public DatePicker setupDateField;
    public TextField entTypeField;
    public TextField industryField;
    public TextField districtField;
    public CheckBox pathExistField;
    public TextField pathField;
    public DatePicker createdDateField;
    public TextField telephoneField;
    public TextField regAddressField;
    public TextField addressField;
    public TextField registeredCapitalField;
    public TextField registeredCapitalCurrencyField;
    public TextField legalRepresentativeField;
    public DatePicker operationPeriodBeginField;
    public DatePicker operationPeriodEndField;
    public TextArea memoField;
    public Label versionLabel;
    public Button companyRenameBtn;
    public Button companyPathCreateBtn;
    public Button companyPathChangeBtn;
    public Button companyPathSameAsNameBtn;

    // private final CompanyCustomerViewModel companyCustomerViewModel = new
    // CompanyCustomerViewModel();
    // private final CompanyVendorViewModel companyVendorViewModel = new
    // CompanyVendorViewModel();

    private final SimpleObjectProperty<CompanyCustomer> companyCustomerProperty = new SimpleObjectProperty<>();
    private final SimpleObjectProperty<CompanyVendor> companyVendorProperty = new SimpleObjectProperty<>();

    public Pane customerTab_pane1;
    public Button customerTab_openBtn;
    public Pane customerTab_pane2;
    public Button customerTab_createBtn;

    public Pane vendorTab_pane1;
    public Button vendorTab_openBtn;
    public Pane vendorTab_pane2;
    public Button vendorTab_createBtn;

    @Override
    public void show(Stage stage) {
        super.show(stage);
        stage.minWidthProperty().set(600);
        stage.minHeightProperty().set(450);
        getTitle().set("[" + viewModel.getId().get() + "] " + viewModel.getName().getValue() + " 公司详情");
    }

    @Override
    protected void registerTabSkins() {
        registerTabSkin(baseInfoTab, tab1 -> new CompanyTabSkinBase(this));
        registerTabSkin(oldNameTab, tab1 -> new CompanyTabSkinOldName(this));
        registerTabSkin(contactTab, tab1 -> new CompanyTabSkinContact(this));
        registerTabSkin(blackReasonTab, tab1 -> new CompanyTabSkinBlackReason(this));
        registerTabSkin(bankAccountTab, tab1 -> new CompanyTabSkinBankAccount(this));
        registerTabSkin(contractTab, tab -> new CompanyTabSkinContract(this));
        registerTabSkin(fileTab, tab -> new CompanyTabSkinFile(this));
        registerTabSkin(invoiceTab, tab -> new CompanyTabSkinInvoice(this));
        registerTabSkin(purchaseBillVoucherTab, tab -> new CompanyTabSkinPurchaseBillVoucher(this));
        registerTabSkin(otherTab, tab -> new CompanyTabSkinOther(this));

        initializeVendorTab();
        initializeCustomerTab();
    }

    @Override
    protected <K extends AbstEntityBasedTabSkin<?, ?, ?>> K registerTabSkin(Tab tab, Function<Tab, K> func) {
        K skin = super.registerTabSkin(tab, func);
        if (skin instanceof AbstCompanyBasedTabSkin b) {
            b.setViewModel(viewModel);
        }
        return skin;
    }

    @Override
    public CompanyService getViewModelService() {
        return companyService;
    }

    private void initializeCustomerTab() {
        customerTab.setOnSelectionChanged(event -> {
            if (logger.isDebugEnabled()) {
                logger.debug("customerTab OnSelectionChanged");
            }
            if (customerTab.isSelected()) {
                onCustomerTabShown();
            }
        });

        customerTab_pane1.visibleProperty().bind(customerTab_pane2.visibleProperty().not());
        customerTab_pane2.visibleProperty().bind(companyCustomerProperty.isNull());
        customerTab_createBtn.setOnAction(event -> {
            // TODO 创建
        });

        customerTab_openBtn.setOnAction(event -> {
            CompanyCustomerWindowController.show(companyCustomerProperty.get(), root.getScene().getWindow());
        });
    }

    private void onCustomerTabShown() {
        if (logger.isDebugEnabled()) {
            logger.debug("onCustomerTabShown");
        }
        getLoadedFuture().thenAcceptAsync(company -> {
            companyCustomerProperty.set(companyCustomerService.findByCompany(company));
        }).exceptionally(ex -> {
            UITools.showExceptionAndWait(ex.getMessage(), ex);
            return null;
        });
    }

    private void initializeVendorTab() {
        vendorTab.setOnSelectionChanged(event -> {
            if (logger.isDebugEnabled()) {
                logger.debug("vendorTab OnSelectionChanged");
            }
            if (vendorTab.isSelected()) {
                onVendorTabShown();
            }
        });

        vendorTab_pane1.visibleProperty().bind(vendorTab_pane2.visibleProperty().not());
        vendorTab_pane2.visibleProperty().bind(companyVendorProperty.isNull());
        vendorTab_createBtn.setOnAction(event -> {
            // TODO 创建
        });

        vendorTab_openBtn.setOnAction(event -> {
            CompanyVendorWindowController.show(companyVendorProperty.get(), root.getScene().getWindow());
        });
    }

    private void onVendorTabShown() {
        if (logger.isDebugEnabled()) {
            logger.debug("onVendorTabShown");
        }
        getLoadedFuture().thenAcceptAsync(company -> {
            if (logger.isDebugEnabled()) {
                logger.debug("onVendorTabShown company {}", company.getName());
            }
            companyVendorProperty.set(companyVendorService.findByCompany(company));
        }).exceptionally(ex -> {
            UITools.showExceptionAndWait(ex.getMessage(), ex);
            return null;
        });
    }

    /**
     * 合并更新企业信息
     */
    public void onCompanyCompositeUpdateAction(ActionEvent event) {
        CompanyCompositeUpdateTasker task = new CompanyCompositeUpdateTasker();
        task.setCompany(getEntity());
        UITools.showTaskDialogAndWait("更新企业信息", task, null);
    }

    /**
     * 企业合规检查
     */
    public void onCompanyVerifyAction(ActionEvent event) {
        Company company = getEntity();
        CompanyVerifyTasker task = new CompanyVerifyTasker();
        task.setCompanyService(companyService);
        task.setCompany(company);
        UITools.showTaskDialogAndWait("企业合规性验证", task, null);
    }

    public void onCompanyOpenInExplorerAction(ActionEvent event) {
        Company company = getEntity();
        String path = company.getPath();

        CompletableFuture.runAsync(() -> {
            if (!StringUtils.hasText(path)) {
                ButtonType buttonType = UITools.showConfirmation("目录未设置", "是否创建目录").join();
                if (buttonType == ButtonType.OK) {
                    if (companyService.makePathAbsent(company)) {
                        save(company);
                    }
                } else {
                    setStatus("未设置目录");
                    return;
                }
            }
            DesktopUtils.checkAndShowInExplorer(company.getPath(), this::setStatus);
        });
    }

}
