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.CustomerCtx;
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.customer.service.CompanyCustomerService;
import com.ecep.contract.model.CloudYu;
import com.ecep.contract.model.Company;
import com.ecep.contract.model.CompanyCustomer;
import com.ecep.contract.model.CompanyCustomerEntity;

import lombok.Setter;

/**
 * 同步客户任务
 */
public class CustomerSyncTask extends AbstContractRepairTasker {
    private static final Logger logger = LoggerFactory.getLogger(CustomerSyncTask.class);
    private YongYouU8Repository repository;
    private final CustomerCtx customerCtx = new CustomerCtx();
    @Setter
    private YongYouU8Service yongYouU8Service;

    public CustomerSyncTask() {
        updateTitle("用友U8系统-同步客户");
    }

    private CompanyCustomerService getCompanyCustomerService() {
        return customerCtx.getCompanyCustomerService();
    }

    @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(customerCtx);

        AtomicInteger counter = new AtomicInteger(0);
        Long total = repository.countAllCustomers();
        updateTitle("用友U8系统-同步客户，合计 " + total + " 条");
        try (Stream<Map<String, Object>> stream = repository.queryAllCustomerForStream()) {
            stream.forEach(rs -> {
                if (isCancelled()) {
                    updateMessage("Cancelled");
                    return;
                }
                try {
                    String cusCode = (String) rs.get("cCusCode");
                    MessageHolder subHolder = holder.sub(counter.get() + " / " + total + "> " + cusCode + " ");
                    boolean modified = false;
                    CompanyCustomerEntity entity = customerCtx.findOrCreateByCode(rs, cusCode, subHolder);
                    Map<String, Object> map = repository.findCustomerByCusCode(entity.getCode());
                    if (map == null) {
                        subHolder.error("客户项不存在：" + cusCode);
                        return;
                    }
                    if (customerCtx.applyEntityDetail(entity, map, subHolder)) {
                        modified = true;
                    }
                    if (modified) {
                        entity = customerCtx.getCompanyCustomerEntityService().save(entity);
                    }
                    updateCompanyNameAndAbbName(entity, subHolder);
                    updateCloudYu(entity);

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

    private void updateCloudYu(CompanyCustomerEntity entity) {
        CompanyCustomer customer = entity.getCustomer();
        if (customer == null) {
            return;
        }
        if (!Hibernate.isInitialized(customer)) {
            customer = getCompanyCustomerService().findById(customer.getId());
        }
        Company company = customer.getCompany();
        if (company == null) {
            return;
        }
        CloudYu cloudYu = yongYouU8Service.getOrCreateCloudYu(company);
        if (cloudYu == null) {
            return;
        }
        cloudYu.setCustomerUpdateDate(LocalDate.now());
        cloudYu.setCloudLatest(Instant.now());
        cloudYu.setExceptionMessage("");
        yongYouU8Service.save(cloudYu);

    }

    private void updateCompanyNameAndAbbName(CompanyCustomerEntity entity, MessageHolder holder) {
        CompanyService companyService = customerCtx.getCompanyService();
        CompanyCustomer customer = entity.getCustomer();
        if (customer == null) {
            return;
        }
        if (!Hibernate.isInitialized(customer)) {
            customer = getCompanyCustomerService().findById(customer.getId());
        }
        Company company = customer.getCompany();
        if (company == null) {
            return;
        }
        if (!Hibernate.isInitialized(company)) {
            company = companyService.findById(company.getId());
        }
        boolean modified = false;
        CompanyCtx companyCtx = customerCtx.getCompanyCtx();
        if (companyCtx.updateCompanyNameIfAbsent(company, entity.getName(), holder)) {
            modified = true;
        }
        if (companyCtx.updateCompanyAbbNameIfAbsent(company, entity.getAbbName(), holder)) {
            modified = true;
        }
        if (modified) {
            companyService.save(company);
        }
    }
}
