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

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huigou.cache.DictUtil;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.base.coderule.application.CodeRuleApplication;

import com.huigou.topsun.sap.common.DefaultHttpClient;
import com.huigou.topsun.sap.common.application.SapMutualEpLogApplication;
import com.huigou.topsun.sap.common.domain.SapResult;
import com.huigou.topsun.sap.transfers.application.SapStockTransfersApplication;
import com.huigou.topsun.sap.transfers.application.SapStockTransfersItemApplication;
import com.huigou.topsun.sap.transfers.domain.SapStockTransfers;
import com.huigou.topsun.sap.transfers.domain.SapStockTransfersItem;
import com.huigou.topsun.sap.transfers.domain.query.SapStockTransfersQueryRequest;
import com.huigou.topsun.sap.transfers.domain.vo.SapStockTransfersItemVO;
import com.huigou.topsun.sap.transfers.domain.vo.SapStockTransfersVO;
import com.huigou.topsun.sap.transfers.repository.SapStockTransfersItemRepository;
import com.huigou.topsun.sap.transfers.repository.SapStockTransfersRepository;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bmp.doc.attachment.application.AttachmentApplication;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;
import com.huigou.util.DateUtil;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: Lxh
 * @Date: 2024/03/27/20:35
 * @Description:
 */
@Service("sapStockTransfersApplication")
public class SapStockTransfersApplicationImpl extends FlowBroker implements SapStockTransfersApplication {
    @Autowired
    private SapStockTransfersRepository sapStockTransfersRepository;
    @Autowired
    private SapStockTransfersItemApplication sapStockTransfersItemApplication;
    @Autowired
    private SapStockTransfersItemRepository sapStockTransfersItemRepository;
    @Autowired
    private AttachmentApplication attachmentApplication;
    @Autowired
    private CodeRuleApplication codeRuleApplication;
    @Autowired
    DefaultHttpClient defaultHttpClient;
    @Autowired
    SapMutualEpLogApplication sapMutualEpLogApplication;

    @Override
    public Map<String, Object> getStockTransfersList(SapStockTransfersQueryRequest queryRequest) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "sapStockTransfers");
        QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
        if (queryRequest.getStatus() != null) {
            queryModel.addCriteria(" and t.status =:status");
            queryModel.putParam("status", queryRequest.getStatus());
        }
        if (queryRequest.getBillCode() != null) {
            queryModel.addCriteria(" and t.bill_code like:billCode");
            queryModel.putLikeParam("billCode", queryRequest.getBillCode());
        }
//        if (queryRequest.getReason() != null) {
//            queryModel.addCriteria(" and t.reason like:reason");
//            queryModel.putLikeParam("reason", queryRequest.getReason());
//        }
        queryModel.putDictionary("ekorg", DictUtil.getDictionary("ekorg"));
        queryModel.putDictionary("status", DictUtil.getDictionary("bizBillStatus"));
        queryModel.addCriteria(" order by bill_code desc ");
        Map<String, Object> map = this.sqlExecutorDao.executeSlicedQuery(queryModel);
        return map;
    }

    @Override
    public SapStockTransfers getStockTransfersById(String id) {
        return sapStockTransfersRepository.findOne(id);
    }

    @Override
    public void deleteByIds(List<String> ids) {
        ids.forEach(id->{
            sapStockTransfersRepository.delete(id);
            List <SapStockTransfersItem> list=sapStockTransfersItemRepository.findByTransfersId(id);
            for (SapStockTransfersItem sapStockTransfersItem:list) {
                sapStockTransfersItemRepository.delete(sapStockTransfersItem);
            }
        });
    }

    @Override
    protected void onBeforeComplete(DelegateTask delegateTask) {
        super.onBeforeComplete(delegateTask);
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        if (this.isApplyProcUnit(delegateTask) && this.getApprovalParameter().isAdvanceProcessAction()) {
            SapStockTransfers sapStockTransfers = sapStockTransfersRepository.findOne(bizId);
            sapStockTransfers.setStatusId(BizBillStatus.APPROVING.getId());
            sapStockTransfersRepository.save(sapStockTransfers);
        }
    }

    @Override
    protected void onEnd(DelegateExecution delegateExecution) {
        super.onEnd(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        BizBillStatus status = approvePassed() ? BizBillStatus.COMPLETED : BizBillStatus.ABORTED;
        SapStockTransfers stockTransfers = sapStockTransfersRepository.findOne(bizId);
        stockTransfers.setStatusId(status.getId());
        sapStockTransfersRepository.save(stockTransfers);

        List <SapStockTransfersItem> itemList= sapStockTransfersItemApplication.findByTransfersId(stockTransfers.getId());
        //推送SAP
        SapStockTransfersVO sapStockTransfersVO=new SapStockTransfersVO();
        BeanUtil.copyProperties(stockTransfers, sapStockTransfersVO);
        List <SapStockTransfersItemVO> newItemList=new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        for (SapStockTransfersItem item:itemList){
            SapStockTransfersItemVO sapStockTransfersItemVO=new SapStockTransfersItemVO();
            BeanUtil.copyProperties(item, sapStockTransfersItemVO);
            if (item.getEeind() != null){
                sapStockTransfersItemVO.setEeind(sdf.format(item.getEeind()));
            }
            sapStockTransfersItemVO.setWerks(stockTransfers.getWerks());
            newItemList.add(sapStockTransfersItemVO);
        }
        sapStockTransfersVO.setItem(newItemList);
        sendSapData(sapStockTransfersVO,stockTransfers.getId());
    }

    @Override
    protected void onAbortProcessInstance(DelegateExecution delegateExecution) {
        super.onAbortProcessInstance(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        SapStockTransfers StockTransfers = sapStockTransfersRepository.findOne(bizId);
        StockTransfers.setStatusId(BizBillStatus.ABORTED.getId());
        sapStockTransfersRepository.save(StockTransfers);
    }

    @Override
    protected void onBack(DelegateTask delegateTask, String destActivityId) {
        super.onBack(delegateTask, destActivityId);
        if ("Apply".equalsIgnoreCase(destActivityId)) {
            String bizId = delegateTask.getExecution().getProcessBusinessKey();
            SapStockTransfers StockTransfers = sapStockTransfersRepository.findOne(bizId);
            StockTransfers.setStatusId(BizBillStatus.APPLYING.getId());
            sapStockTransfersRepository.save(StockTransfers);
        }
    }

    /**
     * 设置任务名称
     */
    @Override
    protected void setTaskDescription(DelegateTask delegateTask) {
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        delegateTask.setDescription(this.getApprovalSubjectName(bizId));
    }

    /**
     * 获取任务标题
     *
     * @param bizId
     * @return
     */
    private String getApprovalSubjectName(String bizId) {
        SapStockTransfers sapStockTransfers = this.sapStockTransfersRepository.findOne(bizId);
        //查询 单据日期
        String fillinDateStr = DateUtil.getDateFormat("yyyy-MM-dd HH:mm:ss", sapStockTransfers.getFillinDate());
        //设置标题
        return String.format("%s-%s(%s)", "公司间内跨工厂调拨申请", sapStockTransfers.getBillCode(), fillinDateStr);
    }

    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        return ClassHelper.toMap(sapStockTransfersRepository.getOne(bizId));
    }

    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        SapStockTransfers StockTransfers = getBizEntity(SapStockTransfers.class);
        if (StockTransfers.isNew()) {
            StockTransfers.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            StockTransfers = (SapStockTransfers) commonDomainService.loadAndFillinProperties(StockTransfers);
        }
        StockTransfers.setBsart("ZUB");
        StockTransfers = sapStockTransfersRepository.save(StockTransfers);
        List<SapStockTransfersItem> items = getBizEntities(SapStockTransfersItem.class, "items");
        if (items.size()<1){
           throw new IllegalArgumentException("没有填写携带物品信息!");
        }
        sapStockTransfersItemApplication.saveSapStockTransfersItems(StockTransfers.getId(),items);
        //更新附件ID为主键ID
//        if (!(StockTransfers.getId().equals(StockTransfers.getAttbizId()))) {
//            List<Attachment> attachmentList = attachmentApplication.queryAttachments("sapRetirementInfo", StockTransfers.getAttbizId());
//            for (Attachment attachment : attachmentList) {
//                attachment.setBizId(StockTransfers.getId());
//                attachmentApplication.saveAttachment(attachment);
//            }
//        }
        return StockTransfers.getId();
    }


    /**
     * 远程调用sap接口，传递数据
     */
    public void sendSapData(SapStockTransfersVO sapStockTransfersVO,String id) {

        ObjectMapper objectMapper = new ObjectMapper();
        String url = "cud_po_zub/po_zub";
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("businessType", "存货转移数据");
        resultMap.put("businessId", id);
        resultMap.put("parameter", JSON.toJSONString(sapStockTransfersVO));
       // List<SapStockTransfersVO> sapStockTransfersVOs = new ArrayList<>();
       // sapStockTransfersVOs.add(sapStockTransfersVO);
        String message = "";
        try {
            String result = defaultHttpClient.execute(sapStockTransfersVO, url);
            List<SapResult> sapResultList = JSONObject.parseArray(result, SapResult.class);
            if (sapResultList.size()<1){
                throw new RuntimeException("数据传输失败，没有收到返回结果：" + sapResultList);
            }
            SapResult sapResult = sapResultList.get(0);
            resultMap.put("sequence", resultMap.get("row"));
            if ("S".equals(sapResult.getTYPE())) {
                SapStockTransfers sapStockTransfers = this.getStockTransfersById(id);
                //  suppliersInfo.setPartner(sapResult.getMESSAGE_V1());
                resultMap.put("TYPE", sapResult.getTYPE());
                resultMap.put("MESSAGE", sapResult.getMESSAGE());
                sapStockTransfers.setType(sapResult.getTYPE());
                sapStockTransfers.setMessage(sapResult.getMESSAGE_V1());
                sapStockTransfersRepository.save(sapStockTransfers);
            } else {
                List<String> stringList = sapResultList.stream().map(SapResult::getMESSAGE).collect(Collectors.toList());
                message = String.join(";", stringList);
                throw new RuntimeException("数据传输失败，请稍后手动重试！" + message);
            }
        } catch (Exception e) {
            resultMap.put("TYPE", "E");
            resultMap.put("MESSAGE", e.getMessage());
            throw new RuntimeException("数据传输失败请检查数据后重试！" + e.getMessage());
        } finally {
            sapMutualEpLogApplication.saveSapMutualEpLog(resultMap);
        }
    }
}
