package com.ecep.contract.cloud.u8;

import java.time.Instant;
import java.time.LocalDate;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

import org.hibernate.Hibernate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.SpringApp;
import com.ecep.contract.cloud.u8.ctx.CompanyCtx;
import com.ecep.contract.cloud.u8.ctx.VendorCtx;
import com.ecep.contract.constant.CloudServiceConstant;
import com.ecep.contract.ds.company.service.CompanyService;
import com.ecep.contract.ds.contract.tasker.AbstContractRepairTasker;
import com.ecep.contract.ds.vendor.service.CompanyVendorEntityService;
import com.ecep.contract.ds.vendor.service.CompanyVendorService;
import com.ecep.contract.model.CloudYu;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyVendor;
import com.ecep.contract.model.CompanyVendorEntity;

import lombok.Setter;

/**
 * 供应商同步任务
 */
public class VendorSyncTask extends AbstContractRepairTasker {
    private static final Logger logger = LoggerFactory.getLogger(VendorSyncTask.class);
    private final VendorCtx vendorCtx = new VendorCtx();
    private CompanyVendorService companyVendorService;
    private CompanyVendorEntityService vendorEntityService;
    private YongYouU8Repository repository;
    @Setter
    private YongYouU8Service yongYouU8Service;

    public VendorSyncTask() {
        updateTitle("用友U8系统-同步供应商");
    }

    private CompanyVendorService getCompanyVendorService() {
        if (companyVendorService == null) {
            companyVendorService = SpringApp.getBean(CompanyVendorService.class);
        }
        return companyVendorService;
    }

    private CompanyVendorEntityService getVendorEntityService() {
        if (vendorEntityService == null) {
            vendorEntityService = SpringApp.getBean(CompanyVendorEntityService.class);
        }
        return vendorEntityService;
    }

    @Override
    protected void repair(MessageHolder holder) {
        try {
            yongYouU8Service = getBean(YongYouU8Service.class);
        } catch (BeansException e) {
            holder.warn("未启用 " + CloudServiceConstant.U8_NAME + " 服务");
            return;
        }
        repository = SpringApp.getBean(YongYouU8Repository.class);
        yongYouU8Service.initialize(vendorCtx);

        AtomicInteger counter = new AtomicInteger(0);
        Long total = repository.countAllVendors();
        updateTitle("用友U8系统-同步供应商，合计 " + total + " 条");

        try (Stream<Map<String, Object>> stream = repository.queryAllVendorForStream()) {
            stream.forEach(rs -> {
                if (isCancelled()) {
                    updateMessage("Cancelled");
                    return;
                }
                try {
                    String venCode = (String) rs.get("cVenCode");
                    MessageHolder subHolder = holder.sub(counter.get() + " / " + total + "> " + venCode + " ");
                    boolean modified = false;
                    CompanyVendorEntity entity = vendorCtx.findOrCreateByCode(venCode, subHolder);
                    Map<String, Object> map = repository.findVendorByVendCode(entity.getCode());
                    if (map == null) {
                        subHolder.error("供应商项不存在：" + venCode);
                        return;
                    }
                    if (vendorCtx.applyEntityDetail(entity, map, subHolder)) {
                        modified = true;
                    }
                    if (modified) {
                        entity = getVendorEntityService().save(entity);
                    }
                    updateCompanyNameAndAbbName(entity, subHolder);
                    updateCloudYu(entity);

                } catch (Exception e) {
                    logger.error("Vendor sync failure {}, data = {}", e.getMessage(), rs, e);
                    updateMessage(e.getMessage());
                    throw e;
                }
                updateProgress(counter.incrementAndGet(), total);
            });
        }
    }

    private void updateCloudYu(CompanyVendorEntity entity) {
        CompanyVendor vendor = entity.getVendor();
        if (vendor == null) {
            return;
        }
        if (!Hibernate.isInitialized(vendor)) {
            vendor = getCompanyVendorService().findById(vendor.getId());
        }
        Company company = vendor.getCompany();
        if (company == null) {
            return;
        }
        CloudYu cloudYu = yongYouU8Service.getOrCreateCloudYu(company);
        if (cloudYu == null) {
            return;
        }
        cloudYu.setVendorUpdateDate(LocalDate.now());
        cloudYu.setCloudLatest(Instant.now());
        cloudYu.setExceptionMessage("");
        yongYouU8Service.save(cloudYu);
    }

    private void updateCompanyNameAndAbbName(CompanyVendorEntity entity, MessageHolder holder) {
        CompanyService companyService = vendorCtx.getCompanyService();
        CompanyVendor vendor = entity.getVendor();
        if (vendor == null) {
            return;
        }
        if (!Hibernate.isInitialized(vendor)) {
            vendor = getCompanyVendorService().findById(vendor.getId());
        }
        Company company = vendor.getCompany();
        if (company == null) {
            return;
        }
        if (!Hibernate.isInitialized(company)) {
            company = companyService.findById(company.getId());
        }
        boolean modified = false;
        CompanyCtx companyCtx = vendorCtx.getCompanyCtx();
        if (companyCtx.updateCompanyNameIfAbsent(company, entity.getName(), holder)) {
            modified = true;
        }
        if (companyCtx.updateCompanyAbbNameIfAbsent(company, entity.getAbbName(), holder)) {
            modified = true;
        }
        if (modified) {
            companyService.save(company);
        }
    }

}
