package com.huigou.topsun.sap.costCenter.application.impl;

import cn.hutool.core.bean.BeanUtil;
import com.huigou.cache.DictUtil;
import com.huigou.cache.SystemCache;
import com.huigou.context.Operator;
import com.huigou.context.OrgUnit;
import com.huigou.context.ThreadLocalUtil;
import com.huigou.topsun.sap.costCenter.application.CostCenterApplication;
import com.huigou.topsun.sap.costCenter.domain.CostCenter;
import com.huigou.topsun.sap.costCenter.domain.TmpCostCenterData;
import com.huigou.topsun.sap.costCenter.repository.CostCenterRepository;
import com.huigou.topsun.sap.costCenter.repository.TmpCostCenterDataRepository;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.ProcessAction;
import com.huigou.uasp.bpm.ProcessStartModel;
import com.huigou.uasp.bpm.engine.application.WorkflowApplication;
import com.huigou.uasp.tool.dataimport.application.ExcelImportInterface;
import com.huigou.util.Constants;
import com.huigou.util.SDO;
import com.huigou.util.StringUtil;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("costCenterDataExcelImport")
public class CostCenterDataExcelImport implements ExcelImportInterface {


    @Autowired
    private TmpCostCenterDataRepository tmpCostCenterDataRepository;
    @Autowired
    private CostCenterRepository costCenterRepository;
    @Autowired
    private WorkflowApplication workflowApplication;
    @Override
    public void executeImport(String batchNumer) {
        List<TmpCostCenterData> centerDataList = tmpCostCenterDataRepository.findByBatchNumber(batchNumer);
        if (!CollectionUtils.isEmpty(centerDataList)){
            List<CostCenter> costCenterList = new ArrayList<>();
            for (TmpCostCenterData tmpCostCenterData : centerDataList) {
                if (StringUtil.isBlank(tmpCostCenterData.getKostl())){
                    throw new RuntimeException("成本中心编码不能为空");
                }
                if (tmpCostCenterData.getKostl().length()!=10){
                    throw new RuntimeException("成本中心编码只能是10位");
                }
                if (StringUtil.isBlank(tmpCostCenterData.getKtext())){
                    throw new RuntimeException("成本中心名称不能为空");
                }
                if (StringUtil.isBlank(tmpCostCenterData.getKosar())){
                    throw new RuntimeException("成本中心类型不能为空");
                }else {
                    //根据名称转换成编码
                    String value = DictUtil.getDictionaryDetailValue("kosar", tmpCostCenterData.getKosar());
                    tmpCostCenterData.setKosar(value);
                }
                if (StringUtil.isBlank(tmpCostCenterData.getKhinr())){
                    throw new RuntimeException("层次结构范围不能为空");
                }
                if (StringUtil.isBlank(tmpCostCenterData.getPrctr())){
                    throw new RuntimeException("利润中心不能为空");
                }else {
                    //根据名称转换成编码
                    String value = DictUtil.getDictionaryDetailValue("prctr", tmpCostCenterData.getPrctr());
                    tmpCostCenterData.setPrctr(value);
                }
                if (tmpCostCenterData.getDatab() == null){
                    throw new RuntimeException("有效截至日不能为空");
                }
                if (tmpCostCenterData.getDatbi() == null){
                    throw new RuntimeException("有效期自不能为空");
                }
                List<CostCenter> centerList = costCenterRepository.findByKostl(tmpCostCenterData.getKostl());
                if (!CollectionUtils.isEmpty(centerList)){
                    centerList.forEach(costCenter -> {
                        //判断相同成本中心编码的是不是已终止的单据，如果不是终止的提示已存在。
                        if (costCenter.getStatusId() != BizBillStatus.ABORTED.getId()){
                            throw new RuntimeException("已存在编码为：" + tmpCostCenterData.getKostl() + "的成本中心");
                        }
                    });
                }
                CostCenter costCenter = new CostCenter();
                BeanUtils.copyProperties(tmpCostCenterData,costCenter);
                costCenter.setIsDelete(0);
                costCenter.setIsEnable(1);
                //costCenter.setStatusId(BizBillStatus.COMPLETED.getId());
                //Org org = orgApplication.loadMainOrgByLoginName(tmpCostCenterData.getCreatedCode());
                //costCenter.setDefaultValues(new OrgUnit(org.getFullId(), org.getFullName()));
                //costCenterApplication.saveCostCenter(costCenter);
                costCenter.setId(null);
                costCenterList.add(costCenter);
            }
            //发起流程
            this.saveCostCenterImportVo(costCenterList);
        }
    }

    public void saveCostCenterImportVo(List<CostCenter> costCenterList) {
        for (CostCenter costCenter : costCenterList) {
            //初始化用户信息
            Operator operator = ThreadLocalUtil.getOperator();
            costCenter.setDefaultValues(new OrgUnit(operator.getFullId(), operator.getFullName()));
            String isCostCenterHis = SystemCache.getParameter("isCostCenterHis", String.class);
            costCenter.setIsCostCenterHis(isCostCenterHis);
            //标识是不是历史数据导入，如果是，则不需要发起流程
            if ("1".equals(isCostCenterHis)){
                costCenter.setTYPE("S");
                costCenter.setMESSAGE("成本中心主数据创建成功！");
                costCenter.setStatusId(BizBillStatus.COMPLETED.getId());
            }else {
                Map<String, Object> formData = BeanUtil.beanToMap(costCenter);
                SDO localSdo = this.buildSDO(formData,operator);
                String bizId = this.startProcessInstance(CostCenterApplication.PROCESS_DEFINITION_KEY, localSdo);
                costCenter.setId(bizId);
                costCenter.setStatusId(BizBillStatus.APPLYING.getId());
            }
        }
        costCenterRepository.save(costCenterList);
    }

    public String startProcessInstance(String processDefinitionKey,SDO localSdo){
        Map<String, Object> variables = new HashMap();
        ThreadLocalUtil.putVariable(Constants.SDO, localSdo);
        variables.put("startModel", ProcessStartModel.MANUAL.getId());
        Operator operator = localSdo.getOperator();
        variables.put("executorFullId", operator.getFullId());
        variables.put("executorFullName", operator.getFullName());
        ThreadLocalUtil.putOperator(operator);
        ThreadLocalUtil.putVariable("client.ip", "127.0.0.1");
        ProcessInstance processInstance = this.workflowApplication.startProcessInstanceByKey(processDefinitionKey, variables);
        return processInstance.getBusinessKey();
    }

    private SDO buildSDO(Map<String, Object> formData,Operator operator) {
        SDO localSdo = new SDO();
        // 将业务数据传递给工作流
        formData.forEach(localSdo::putProperty);
        // 将业务流程信息传递给工作流
        localSdo.putProperty("processAction", ProcessAction.SAVE);
        localSdo.putProperty("procUnitId", "Apply");
        localSdo.setOperator(operator);
        return localSdo;
    }

}
