package com.ecep.contract.controller.project;

import java.util.List;
import java.util.function.BiFunction;

import org.controlsfx.control.textfield.AutoCompletionBinding;
import com.ecep.contract.util.ProxyUtils;
import org.springframework.util.StringUtils;

import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.tab.TabSkin;
import com.ecep.contract.converter.CompanyStringConverter;
import com.ecep.contract.converter.EntityStringConverter;
import com.ecep.contract.model.Bank;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyBankAccount;
import com.ecep.contract.model.CompanyContact;
import com.ecep.contract.model.CompanyInvoiceInfo;
import com.ecep.contract.service.BankService;
import com.ecep.contract.service.CompanyBankAccountService;
import com.ecep.contract.service.CompanyContactService;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.util.FxmlPath;
import com.ecep.contract.util.UITools;

import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.util.StringConverter;

@FxmlPath("/ui/project/project-tab-customer.fxml")
public class ProjectTabSkinCustomerInfo
        extends AbstProjectBasedTabSkin
        implements TabSkin {
    @FXML
    public TextField companyField;
    @FXML
    public Button companyDetailBtn;
    @FXML
    public Label companyLabel;
    @FXML
    public TextField bankAccountField;
    @FXML
    public Label bankAccountLabel;
    @FXML
    public TextField invoiceInfoField;
    @FXML
    public Label invoiceInfoLabel;
    @FXML
    public TextField mainContactField;
    @FXML
    public Label mainContactLabel;
    @FXML
    public TextField subContactField;
    @FXML
    public Label subContactLabel;

    private CompanyService companyService;
    private BankService bankService;
    private CompanyInvoiceInfoService invoiceInfoService;
    private CompanyBankAccountService bankAccountService;
    private CompanyContactService contactService;


    public ProjectTabSkinCustomerInfo(ProjectWindowController controller) {
        super(controller);
    }

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

    @Override
    public void initializeTab() {
        initCompanyField();
        initBankAccountField();
        initInvoiceInfoField();
        initMainContactField();
        initSubContactField();
    }


    private void initCompanyField() {
        companyAutoCompletion(companyField, companyLabel, viewModel.getCustomer()).setOnAutoCompleted(event -> {
            Company company = event.getCompletion();
            viewModel.getCustomer().set(company);

//
//            updateAbsent(company.getUniscid(), companyTaxCodeField.textProperty());
//            updateAbsent(company.getTelephone(), companyTelField.textProperty());
//
//            updateAbsent(
//                    // 优先使用通讯地址
//                    StringUtils.hasText(company.getAddress()) ? company.getAddress() : company.getRegAddr(),
//                    companyAddressField.textProperty());

//            viewModel.getInvoiceInfo();


        });

        companyDetailBtn.setOnAction(event -> {
            Company company = viewModel.getCustomer().get();
            if (company == null) {
                return;
            }
            CompanyWindowController.show(company, controller.root.getScene().getWindow());
        });
    }

    private void initBankAccountField() {
        bankAccountAutoCompletion(bankAccountField, bankAccountLabel, viewModel.getBankAccount()).setOnAutoCompleted(event -> {
            CompanyBankAccount account = event.getCompletion();
            viewModel.getBankAccount().set(account);
        });
    }


    private void initInvoiceInfoField() {
        invoiceInfoAutoCompletion(invoiceInfoField, invoiceInfoLabel, viewModel.getInvoiceInfo()).setOnAutoCompleted(event -> {
            CompanyInvoiceInfo invoiceInfo = event.getCompletion();
            viewModel.getInvoiceInfo().set(invoiceInfo);
        });
    }


    private void initMainContactField() {
        contactAutoCompletion(mainContactField, mainContactLabel, viewModel.getMainContact()).setOnAutoCompleted(event -> {
            CompanyContact contact = event.getCompletion();
            viewModel.getMainContact().set(contact);
        });
    }

    private void initSubContactField() {
        contactAutoCompletion(subContactField, subContactLabel, viewModel.getSubContact()).setOnAutoCompleted(event -> {
            CompanyContact contact = event.getCompletion();
            viewModel.getSubContact().set(contact);
        });
    }

    /**
     * 更新 property 未为空时
     *
     * @param value    要设置的值
     * @param property 要设置的 property
     */
    private void updateAbsent(String value, StringProperty property) {
        if (!StringUtils.hasText(value)) {
            return;
        }
        if (StringUtils.hasText(property.get())) {
            return;
        }
        property.set(value);
    }

    private AutoCompletionBinding<Company> companyAutoCompletion(TextField textField, Label label, SimpleObjectProperty<Company> property) {
        CompanyStringConverter converter = SpringApp.getBean(CompanyStringConverter.class);

        label.textProperty().bind(property.map(company -> {
            if (company == null) {
                return "未选择";
            }

            if (!ProxyUtils.isInitialized(company)) {
                company = getCompanyService().findById(company.getId());
                property.set(company);
            }
            StringBuilder sb = new StringBuilder();
            sb.append("经营状态：");
            sb.append(company.getEntStatus());
            sb.append("\n");

            sb.append("统一社会信用代码：");
            sb.append(company.getUniscid());
            sb.append("\n");

            sb.append("注册电话：");
            sb.append(company.getTelephone());
            sb.append("\n");

            sb.append("注册地址：");
            sb.append(company.getRegAddr());
            return sb.toString();
        }));

        return UITools.autoCompletion(textField, property, converter::suggest, converter);
    }

    private AutoCompletionBinding<CompanyBankAccount> bankAccountAutoCompletion(TextField textField, Label label, SimpleObjectProperty<CompanyBankAccount> property) {
        EntityStringConverter<CompanyBankAccount> converter = new EntityStringConverter<>();
        converter.setInitialized(account -> getBankAccountService().findById(account.getId()));

        label.textProperty().bind(property.map(account -> {
            if (account == null) {
                return "未选择";
            }
            if (!ProxyUtils.isInitialized(account)) {
                account = getBankAccountService().findById(account.getId());
                property.set(account);
            }
            StringBuilder sb = new StringBuilder();
            sb.append("开户行：");
            Bank bank = account.getBank();
            if (bank != null) {
                if (!ProxyUtils.isInitialized(bank)) {
                    bank = getBankService().findById(bank.getId());
                    account.setBank(bank);
                }
                sb.append(bank.toPrettyString());
                sb.append(" ");
            }
            sb.append(account.getOpeningBank());
            sb.append("\n");

            sb.append("开户账号：");
            sb.append(account.getAccount());
            return sb.toString();
        }));
        return autoCompletion(textField, property, getBankAccountService()::searchByCompany, converter);
    }

    private AutoCompletionBinding<CompanyInvoiceInfo> invoiceInfoAutoCompletion(TextField textField, Label label, SimpleObjectProperty<CompanyInvoiceInfo> property) {
        EntityStringConverter<CompanyInvoiceInfo> converter = new EntityStringConverter<>();
        converter.setInitialized(info -> getInvoiceInfoService().findById(info.getId()));

        label.textProperty().bind(property.map(info -> {
            if (info == null) {
                return "未选择";
            }
            if (!ProxyUtils.isInitialized(info)) {
                info = getInvoiceInfoService().findById(info.getId());
                property.set(info);
            }
            StringBuilder sb = new StringBuilder();
            sb.append("发票抬头：");
            sb.append(info.getName());
            sb.append("\n");

            sb.append("纳税人识别号：");
            sb.append(info.getTaxId());
            sb.append("\n");

            sb.append("地址：");
            sb.append(info.getAddress());
            sb.append("\n");

            sb.append("电话：");
            sb.append(info.getPhone());
            return sb.toString();
        }));
        return autoCompletion(textField, property, getInvoiceInfoService()::searchByCompany, converter);
    }

    private AutoCompletionBinding<CompanyContact> contactAutoCompletion(TextField textField, Label label, SimpleObjectProperty<CompanyContact> property) {
        EntityStringConverter<CompanyContact> converter = new EntityStringConverter<>();
        converter.setInitialized(contact -> getContactService().findById(contact.getId()));

        label.textProperty().bind(property.map(contact -> {
            if (contact == null) {
                return "未选择";
            }
            if (!ProxyUtils.isInitialized(contact)) {
                contact = getContactService().findById(contact.getId());
                property.set(contact);
            }
            StringBuilder sb = new StringBuilder();
            sb.append("联系人：");
            sb.append(contact.getName());

            sb.append("\n");
            sb.append("职位：");
            sb.append(contact.getPosition());

            sb.append("\n");
            sb.append("电话：");
            sb.append(contact.getPhone());

            sb.append("\n");
            sb.append("邮箱：");
            sb.append(contact.getEmail());

            return sb.toString();
        }));
        return autoCompletion(textField, property, getContactService()::searchByCompany, converter);
    }

    public <T> AutoCompletionBinding<T> autoCompletion(
            TextField textField,
            SimpleObjectProperty<T> property,
            BiFunction<Company, String, List<T>> func,
            StringConverter<T> converter
    ) {
        return UITools.autoCompletion(textField, property, text -> {
            Company company = viewModel.getCustomer().get();
            if (company == null) {
                return null;
            }
            return func.apply(company, text.getUserText());
        }, converter);
    }

    public CompanyService getCompanyService() {
        if (companyService == null) {
            companyService = getBean(CompanyService.class);
        }
        return companyService;
    }

    public BankService getBankService() {
        if (bankService == null) {
            bankService = getBean(BankService.class);
        }
        return bankService;
    }

    public CompanyInvoiceInfoService getInvoiceInfoService() {
        if (invoiceInfoService == null) {
            invoiceInfoService = getBean(CompanyInvoiceInfoService.class);
        }
        return invoiceInfoService;
    }

    public CompanyBankAccountService getBankAccountService() {
        if (bankAccountService == null) {
            bankAccountService = getBean(CompanyBankAccountService.class);
        }
        return bankAccountService;
    }

    public CompanyContactService getContactService() {
        if (contactService == null) {
            contactService = getBean(CompanyContactService.class);
        }
        return contactService;
    }
}
