package com.sw.mes.sap.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.annotation.Jinko;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.dto.wms.ReportSapWorkinghoursDto;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.sap.dao.ReportSapWorkinghoursDao;
import com.sw.mes.sap.entity.ReportSapWorkinghours;
import com.sw.mes.sap.service.ReportSapWorkinghoursService;
import com.sw.mes.sap.service.SAPOutputServiceService;
import com.sw.mes.sap.task.SapWorkinghoursQueueCache;
import com.sw.mes.utils.CodeUtil;
import com.sw.mes.utils.StringUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * MES报工SAP工时接口Service业务层处理
 *
 * @author liru
 * @date 2024-01-07
 */
@Slf4j
@Service
@Transactional
@Jinko(value="MES报工SAP工时接口Service业务层处理",author = "liru")
public class ReportSapWorkinghoursServiceImpl extends BaseServiceImpl<ReportSapWorkinghours> implements ReportSapWorkinghoursService
{
    

	private ReportSapWorkinghoursDao dao;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private SAPOutputServiceService sAPOutputServiceService;
    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    public void setDao(ReportSapWorkinghoursDao dao) {
        super.setBaseDao(dao);
        this.dao=dao;
    }
    
    
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
	public void saveOrUpdate(ReportSapWorkinghours t) {
    	
    	boolean isInsert = false;
    	if(t.getId()==null) {
    		isInsert = true;
    	}
    	
		super.saveOrUpdate(t);
		
		//新增时触发自动报工验证
		autoSendReportSapWorkinghours(t, isInsert);
	}

	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void autoSendReportSapWorkinghours(ReportSapWorkinghours t, boolean isInsert) {
		if (isInsert) {

			DictionaryItem switchValue = dictionaryItemService.findByThemeValueAndNameAndEnable("AutoReportSwitch",
					"WorkinghoursAuto", true);
			if (StringUtils.isNotBlank(switchValue.getValue()) && switchValue.getValue().equalsIgnoreCase("true")) {
				if (StringUtils.isBlank(switchValue.getExtendValue1())
						|| (StringUtils.isNotBlank(switchValue.getExtendValue1())
								&& switchValue.getExtendValue1().contains(t.getProcName()))) {

					if (t.getAsyn()) {// 程序异步处理
						// spring 管理单线程队列异步执行发送SAP信息
						// sapGoodsmvtDataAsyncService.sapGoodsmvtDataHandler(this,reportSapGoodsmvt.getId());
						// 添加异步处理缓存中
						SapWorkinghoursQueueCache.getInstance().addCache(t.getId());
					} else {// 手动同步处理
						List<Result> results = sendReportWord(new Long[] { t.getId() }, "AUTO");
						for (Result result : results) {
							if (result.getCode().equals(ResultCode.FAIL.getCode())) {
								log.error("自动报工时失败:{}", result.getMessage());
							}
						}
					}
				}
			}
		}
	}

    @Override
    public List<Result> sendReportWord(Long[] ids,String sendType) {
    	List<Result> results = new ArrayList<Result>();
    	
        for (Long id : ids){
        	List<ReportSapWorkinghoursDto> dtolist = new ArrayList<>();
            ReportSapWorkinghours reportSapWorkinghours = get(id);
            String zuuid = CodeUtil.getUniqueCode(reportSapWorkinghours.getId());
            Date cDate = new Date();
            reportSapWorkinghours.setSendType(sendType);
            ReportSapWorkinghoursDto dto = toEagerDto(reportSapWorkinghours);
            
            if(StringUtils.isNotBlank(dto.getRecordId())){
            	dto.setRecordId(dto.getRecordId());
            }else{
            	dto.setRecordId(zuuid);
            }
            
            if (dto.getCnfDate() != null) {
            	dto.setCnfDate(dto.getCnfDate());
            }else{
            	dto.setCnfDate(cDate);
            }
            
            
            
            dtolist.add(dto);
        
	        //格式化工时报工数据
	        JSONArray items = JSONArray.parseArray(JSONArray.toJSONString(dtolist));
	        String msg = "";
	        String errorInfo = null;
	        Boolean isError = true;
	        try {
	            JSONObject jsonObject = sAPOutputServiceService.sendWorkinghoursToSap(items);
	            JSONObject ES_BC_INFO = jsonObject.getJSONObject("ES_BC_INFO");
	            String resultState = ES_BC_INFO.getString("TYPE");
	            if(StringUtils.isNotBlank(resultState) && resultState.equals("E")){
	            	msg = ES_BC_INFO.getString("MSG");
	            	Result result = ResultGenerator.fail("ID("+id+"):"+msg);
	            	results.add(result);
	            	isError = false;
			    	errorInfo = msg;
	            }
	        } catch (Exception e) {
	        	e.printStackTrace();
	        	Result result = ResultGenerator.fail("ID("+id+"):"+e.getMessage());
            	results.add(result);
            	isError = false;
            	errorInfo = e.getMessage();
	        }
	        
	        reportSapWorkinghours.setRecordId(dto.getRecordId());
	        
	        if(isError) {
	        	errorInfo = null;//成功后清除异常原因
	        	Result result = ResultGenerator.success();
            	results.add(result);
            	reportSapWorkinghours.setCnfDate(dto.getCnfDate());
	        	reportSapWorkinghours.setStatus(true);
	        }
	        
	        reportSapWorkinghours.setErrorInfo(errorInfo);
	
	        //构造发送数据格式
            saveOrUpdate(reportSapWorkinghours);
        }
        
        return results;
    }

    @Override
	public ReportSapWorkinghours findByRemarkAndProcName(String remark, String procName) {
    	return  dao.findByRemarkAndProcName(remark, procName);
	}

    @Override
	public List<ReportSapWorkinghoursDto> findByRemarkAndProcNameAndCrystalNo(String remark, String procName, String crystalNo) {
    	return  dao.findByRemarkAndProcNameAndCrystalNo(remark, procName, crystalNo);
	}

    public ReportSapWorkinghoursDto toEagerDto(ReportSapWorkinghours entity) {
        return modelMapper.map(entity, ReportSapWorkinghoursDto.class);
    }


	@Override
	public Long getSendSapLog(String aUFNR) {
		return dao.getSendSapLog(aUFNR);
	}
}
