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

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.huigou.data.domain.model.CommonDomainConstants;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.sap.common.DefaultHttpClient;
import com.huigou.topsun.sap.common.domain.SapResult;
import com.huigou.topsun.sap.costReimbursement.domain.SapCostReimbursement;
import com.huigou.topsun.sap.nonProducePick.application.NonProducePickApplication;
import com.huigou.topsun.sap.nonProducePick.application.NonProducePickItemApplication;
import com.huigou.topsun.sap.nonProducePick.domain.NonProducePick;
import com.huigou.topsun.sap.nonProducePick.domain.NonProducePickItem;
import com.huigou.topsun.sap.nonProducePick.domain.query.NonProducePickQueryRequest;
import com.huigou.topsun.sap.nonProducePick.repository.NonProducePickRepository;
import com.huigou.topsun.sap.nonProducePick.vo.CheckNonProducePickItemNumVo;
import com.huigou.topsun.sap.nonProducePick.vo.NonProducePickItemVo;
import com.huigou.topsun.sap.nonProducePick.vo.NonProducePickVo;
import com.huigou.topsun.sap.purchase.domain.SapPurchase;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;
import com.huigou.util.DateUtil;
import com.huigou.util.StringUtil;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: xin.lu
 * @Date: 2024/03/13/9:45
 * @Description:
 */
@Service("nonProducePickApplication")
public class NonProducePickApplicationImpl extends FlowBroker implements NonProducePickApplication {
    @Autowired
    private NonProducePickRepository nonProducePickRepository;
    @Autowired
    private NonProducePickItemApplication nonProducePickItemApplication;
    @Autowired
    private DefaultHttpClient httpClient;
    @Override
    public NonProducePick findNonProducePickById(String id) {
        return nonProducePickRepository.findOne(id);
    }

    @Override
    public void deleteNonProducePickById(List<String> ids) {
        ids.forEach(id->{
            nonProducePickRepository.delete(id);
        });
    }

    @Override
    public NonProducePick saveNonProducePick(NonProducePick nonProducePick) {
        return nonProducePickRepository.save(nonProducePick);
    }

    @Override
    public Map<String, Object> slicedNonProducePickList(NonProducePickQueryRequest queryRequest) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "nonProducePick");
        QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
        queryModel.putDictionary("status",BizBillStatus.getMap());
        Map<String, Object> map = this.sqlExecutorDao.executeSlicedQuery(queryModel);
        return map;
    }

    @Override
    public void sendNonProducePickData(NonProducePick nonProducePick,String ztype) {
        //List<NonProducePickVo> nonProducePickVoList = new ArrayList<>();
        NonProducePickVo nonProducePickVo = new NonProducePickVo();
        nonProducePickVo.setRsnum(nonProducePick.getMessage());
        nonProducePickVo.setZtype(ztype);
        //审批通过，不传ztype，state传3
        if (StringUtil.isBlank(ztype)){
            nonProducePickVo.setState("3");
        }
        nonProducePickVo.setBster(DateUtil.getDateFormat("yyyyMMdd",nonProducePick.getFillinDate()));
        nonProducePickVo.setWerks(nonProducePick.getWerks());
        nonProducePickVo.setUsnam(nonProducePick.getPersonMemberName());
        nonProducePickVo.setKostl(nonProducePick.getKostl());
        nonProducePickVo.setAufnr(nonProducePick.getAufnr());
        //若填写了成本中心，领料采用移动类型201；填写了内部订单，领料采用移动类型261，两者不可并存，SAP发起的刀工模板具领料采用移动类型Z01
        if (StringUtil.isNotBlank(nonProducePick.getKostl())){
            nonProducePickVo.setBwart("201");
        } else if (StringUtil.isNotBlank(nonProducePick.getAufnr())) {
            nonProducePickVo.setBwart("261");
        }

        List<NonProducePickItem> pickItemList = nonProducePickItemApplication.findByNonProducePickId(nonProducePick.getId());
        List<NonProducePickItemVo> pickItemVoList = pickItemList.stream().map(pickItem -> {
            NonProducePickItemVo nonProducePickItemVo = new NonProducePickItemVo();
            BeanUtils.copyProperties(pickItem, nonProducePickItemVo);
            nonProducePickItemVo.setWerks(nonProducePick.getWerks());
            nonProducePickItemVo.setErfme(pickItem.getMeins());
            nonProducePickItemVo.setResItem(pickItem.getRspos());
            return nonProducePickItemVo;
        }).collect(Collectors.toList());
        nonProducePickVo.setItems(pickItemVoList);
        //nonProducePickVoList.add(nonProducePickVo);
        try {
            String execute = httpClient.execute(nonProducePickVo, "cud_ro/cud_ro");
            List<SapResult> resultList = JSONObject.parseArray(execute, SapResult.class);
            SapResult sapResult = resultList.get(0);
            if (!"S".equals(sapResult.getTYPE())){
                throw new RuntimeException("数据传输失败，"+ sapResult.getMESSAGE());
            }
            nonProducePick.setType(sapResult.getTYPE());
            if ("Y".equals(ztype)){
                nonProducePick.setMessage(sapResult.getMESSAGE_V1());
            }
//            else if ("N".equals(ztype)){
//                nonProducePick.setMessage(sapResult.getMESSAGE());
//            }else if (StringUtil.isBlank(ztype)){
//                nonProducePick.setMessage(sapResult.getMESSAGE());
//            }
            nonProducePickRepository.save(nonProducePick);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        NonProducePick nonProducePick = getBizEntity(NonProducePick.class);
        List<NonProducePickItem> nonProducePickItems = getBizEntities(NonProducePickItem.class, "items");
        if (nonProducePick.isNew()) {
            nonProducePick.setStatusId(BizBillStatus.APPLYING.getId());
            //根据工厂。物料，单位检查可用数量
        } else {
            nonProducePick = (NonProducePick) commonDomainService.loadAndFillinProperties(nonProducePick);
        }
        //还未创建预留单之前都需要校验数量
//        if (StringUtil.isBlank(nonProducePick.getMessage())){
//            this.checkNonProducePickNum(nonProducePickItems, nonProducePick.getWerks());
//        }
        nonProducePick = nonProducePickRepository.save(nonProducePick);
        nonProducePickItemApplication.saveNonProducePickItems(nonProducePick.getId(),nonProducePickItems);
        return nonProducePick.getId();
    }

    public void checkNonProducePickNum(List<NonProducePickItem> nonProducePickItems,String werks){
        List<CheckNonProducePickItemNumVo> collect = nonProducePickItems
                .stream()
                .map(nonProducePickItem -> {
                    CheckNonProducePickItemNumVo checkNonProducePickItemNumVo = new CheckNonProducePickItemNumVo();
                    BeanUtils.copyProperties(nonProducePickItem, checkNonProducePickItemNumVo);
                    checkNonProducePickItemNumVo.setWerks(werks);
                    return checkNonProducePickItemNumVo;
                }).collect(Collectors.toList());
        try {
            //http://192.168.3.109:8000/sap/bc/erp_ep/mm_check?sap-client=300
            String execute = httpClient.execute(collect, "mm_check");
            List<SapResult> resultList = JSONObject.parseArray(execute, SapResult.class);
            SapResult sapResult = resultList.get(0);
            if (!"S".equals(sapResult.getTYPE())){
                List<String> stringList = resultList.stream().map(SapResult::getMESSAGE).collect(Collectors.toList());
                String message = String.join(";", stringList);
                throw new RuntimeException(message);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        // 返回业务数据给流程实例，
        return ClassHelper.toMap(nonProducePickRepository.getOne(bizId));
    }
    /**
     * 流程撤销事件
     **/
    @Override
    protected void onRecallProcessInstance(DelegateExecution delegateExecution) {
        String bizId = delegateExecution.getProcessBusinessKey();
        // 修改单据状态为申请
        updateStatus(bizId, BizBillStatus.APPLYING);
    }

    /**
     * 任务完成前执行
     */
    @Override
    protected void onBeforeComplete(DelegateTask delegateTask) {
        super.onBeforeComplete(delegateTask);
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        if (this.isApplyProcUnit(delegateTask) && this.getApprovalParameter().isAdvanceProcessAction()) {
            updateStatus(bizId, BizBillStatus.APPROVING);
        }
        NonProducePick nonProducePick = nonProducePickRepository.findOne(bizId);
        //第一次提交推送到SAP
        if (StringUtil.isBlank(nonProducePick.getMessage()) && this.getApprovalParameter().isAdvanceProcessAction()){
            this.sendNonProducePickData(nonProducePick,"Y");
        }
    }

    /**
     * 回收事件
     **/
    @Override
    protected void onWithdraw(DelegateTask delegateTask, String destActivityId) {
        super.onWithdraw(delegateTask, destActivityId);
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        if (destActivityId.equalsIgnoreCase("apply")) {
            updateStatus(bizId, BizBillStatus.APPLYING);
        }
    }

    @Transactional
    private void updateStatus(String bizId, BizBillStatus status) {
        Assert.hasText(bizId, CommonDomainConstants.ID_NOT_BLANK);
        this.commonDomainService.updateStatus(NonProducePick.class, bizId, status.getId());
    }

    @Override
    protected void onEnd(DelegateExecution delegateExecution) {
        super.onEnd(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        BizBillStatus status = approvePassed() ? BizBillStatus.COMPLETED : BizBillStatus.ABORTED;
        NonProducePick nonProducePick = nonProducePickRepository.findOne(bizId);
        this.sendNonProducePickData(nonProducePick,"");
        nonProducePick.setStatusId(status.getId());
        nonProducePickRepository.save(nonProducePick);
    }

    @Override
    protected void onAbortProcessInstance(DelegateExecution delegateExecution) {
        super.onAbortProcessInstance(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        NonProducePick nonProducePick = nonProducePickRepository.findOne(bizId);
        nonProducePick.setStatusId(BizBillStatus.ABORTED.getId());
        nonProducePickRepository.save(nonProducePick);
        //终止推送到SAP
        this.sendNonProducePickData(nonProducePick,"N");
    }

    /**
     * @param delegateTask
     * @param destActivityId 回退到的目标节点id
     */
    @Override
    protected void onBack(DelegateTask delegateTask, String destActivityId) {
        super.onBack(delegateTask, destActivityId);
        if ("Apply".equalsIgnoreCase(destActivityId)) {
            String bizId = delegateTask.getExecution().getProcessBusinessKey();
            NonProducePick nonProducePick = nonProducePickRepository.findOne(bizId);
            nonProducePick.setStatusId(BizBillStatus.APPLYING.getId());
            nonProducePickRepository.save(nonProducePick);
        }
    }

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

    /**
     * 获取任务标题
     *
     * @param bizId
     * @return
     */
    private String getApprovalSubjectName(String bizId) {
        NonProducePick producePick = this.nonProducePickRepository.findOne(bizId);
        //查询 单据日期
        String fillinDateStr = DateUtil.getDateFormat("yyyy-MM-dd HH:mm:ss", producePick.getFillinDate());
        //设置标题
        return String.format("%s-%s(%s)", "其他物品领发料", producePick.getBillCode(), fillinDateStr);
    }
}
