package com.ecep.contract.controller.tab;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Map;

import org.springframework.data.domain.Pageable;

import com.ecep.contract.MyDateTimeUtils;
import com.ecep.contract.SpringApp;
import com.ecep.contract.controller.company.CompanyWindowController;
import com.ecep.contract.controller.vendor.VendorBidWindowController;
import com.ecep.contract.converter.CompanyStringConverter;
import com.ecep.contract.converter.EntityStringConverter;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractBidVendor;
import com.ecep.contract.model.ContractFile;
import com.ecep.contract.service.CompanyService;
import com.ecep.contract.service.ContractFileService;
import com.ecep.contract.util.ParamUtils;
import com.ecep.contract.util.UITools;
import com.ecep.contract.vm.BaseViewModel;
import com.ecep.contract.vm.ContractBidVendorViewModel;
import com.ecep.contract.vm.ContractFileViewModel;

import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.util.converter.LocalDateStringConverter;
import lombok.Setter;

public class VendorBidTabSkinBase
        extends AbstEntityBasedTabSkin<VendorBidWindowController, ContractBidVendor, ContractBidVendorViewModel>
        implements TabSkin {

    @Setter
    private ContractFileService companyContactService;
    @Setter
    private CompanyService companyService;
    private final ContractFileViewModel quotationSheetViewModel = new ContractFileViewModel();

    private final SimpleBooleanProperty changed = new SimpleBooleanProperty(false);

    public VendorBidTabSkinBase(VendorBidWindowController controller) {
        super(controller);
    }

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

    @Override
    public BooleanProperty changeProperty() {
        return changed;
    }

    @Override
    public void initializeTab() {

        changed.bind(Bindings.createBooleanBinding(() -> {
            return viewModel.getChanged().get() || quotationSheetViewModel.getChanged().get();
        }, viewModel.getChanged(), quotationSheetViewModel.getChanged()));

        initializeCompanyFieldAutoCompletion(controller.companyField);
        initializeFileFieldAutoCompletion(controller.fileField);

        LocalDateStringConverter converter = new LocalDateStringConverter(DateTimeFormatter.ISO_LOCAL_DATE, null);

        controller.developDateField.setConverter(converter);
        controller.developDateField.valueProperty().bindBidirectional(quotationSheetViewModel.getApplyDate());

        viewModel.getQuotationSheet()
                .addListener((observable, oldValue, newValue) -> quotationSheetViewModel.update(newValue));
        quotationSheetViewModel.getApplyDate()
                .addListener((observable, oldValue, newValue) -> quotationSheetViewModel.getChanged().set(true));

        // controller.pathField.textProperty().bind(viewModel.getPath());

        // controller.descriptionField.textProperty().bindBidirectional(viewModel.getDescription());

        // controller.createdField.textProperty().bind(
        // Bindings.createStringBinding(
        // () -> localDateTimeFormatter(viewModel.getCreated()),
        // viewModel.getCreated())
        // );
        // controller.versionLabel.textProperty().bind(viewModel.getVersion().asString());

        controller.relativeCompanyBtn.disableProperty().bind(viewModel.getCompany().isNull());
        controller.relativeCompanyBtn.setOnAction(event -> {
            Company company = viewModel.getCompany().get();
            if (company != null) {
                CompanyWindowController.show(company, controller.tabPane.getScene().getWindow());
            }
        });

        if (viewModel.getQuotationSheet().get() != null) {
            quotationSheetViewModel.update(viewModel.getQuotationSheet().get());
        }
    }

    protected String localDateTimeFormatter(SimpleObjectProperty<LocalDateTime> property) {
        LocalDateTime dateTime = property.get();
        if (dateTime == null) {
            return "";
        }
        return MyDateTimeUtils.format(dateTime);
    }

    private void initializeFileFieldAutoCompletion(TextField textField) {
        EntityStringConverter<ContractFile> stringConverter = new EntityStringConverter<>();
        stringConverter.setInitialized(cc -> getContractFileService().findById(cc.getId()));
        stringConverter.setFormater(ContractFile::getFileName);
        stringConverter.setSuggestion(p -> {
            Contract contract = viewModel.getContract().get();
            if (contract == null) {
                return new ArrayList<>();
            }
            Map<String, Object> params = ParamUtils.builder().equals("contract", contract.getId()).build();
            params.put("searchText", p);
            return getContractFileService().findAll(params, Pageable.ofSize(10)).getContent();
        });
        UITools.autoCompletion(textField, viewModel.getQuotationSheet(), stringConverter::suggest, stringConverter);
    }

    private void initializeCompanyFieldAutoCompletion(TextField textField) {
        CompanyStringConverter converter = SpringApp.getBean(CompanyStringConverter.class);
        UITools.autoCompletion(textField, viewModel.getCompany(), converter::suggest, converter);
    }

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

    public ContractFileService getContractFileService() {
        if (companyContactService == null) {
            companyContactService = SpringApp.getBean(ContractFileService.class);
        }
        return companyContactService;
    }

    @Override
    public void setChanged(boolean changed) {
        viewModel.setChanged(changed);
    }

    @Override
    public void save() {
        super.save();

        if (quotationSheetViewModel.isChanged()) {
            ContractFile contractFile = getContractFileService().findById(quotationSheetViewModel.getId().get());
            if (quotationSheetViewModel.copyTo(contractFile)) {
                contractFile = getContractFileService().save(contractFile);
                BaseViewModel.updateInFxApplicationThread(contractFile, quotationSheetViewModel);
                quotationSheetViewModel.setChanged(false);
            }
        }
    }
}
