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

import cn.hutool.core.bean.BeanUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.sap.purchase.application.SapPurchaseApplication;
import com.huigou.topsun.sap.purchase.application.SapPurchaseItemApplication;
import com.huigou.topsun.sap.purchase.domain.SapPurchase;
import com.huigou.topsun.sap.purchase.domain.SapPurchaseItem;
import com.huigou.topsun.sap.purchase.domain.query.SapPurchaseQueryRequest;
import com.huigou.topsun.sap.purchase.domain.vo.SapPurchaseVo;
import com.huigou.topsun.sap.purchase.repository.SapPurchaseRepository;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Auther: xin.lu
 * @Date: 2023/12/27/10:38
 * @Description:
 */
@Service("sapPurchaseApplication")
public class SapPurchaseApplicationImpl extends FlowBroker implements SapPurchaseApplication {
    @Resource
    private SapPurchaseRepository sapPurchaseRepository;
    @Resource
    private SapPurchaseItemApplication sapPurchaseItemApplication;
    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        SapPurchase sapPurchase = getBizEntity(SapPurchase.class);
        if (sapPurchase.isNew()) {
            sapPurchase.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            sapPurchase = (SapPurchase) commonDomainService.loadAndFillinProperties(sapPurchase);
        }
        sapPurchase = sapPurchaseRepository.save(sapPurchase);
        List<SapPurchaseItem> sapPurchaseItems = getBizEntities(SapPurchaseItem.class, "sapPurchaseItems");
        sapPurchaseItemApplication.saveSapPurchaseItems(sapPurchase.getId(),sapPurchaseItems);

        String sapPurchaseVoJson = this.getSapPurchaseVoJson(sapPurchase);
        return sapPurchase.getId();
    }



    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        // 返回业务数据给流程实例，
        return ClassHelper.toMap(sapPurchaseRepository.getOne(bizId));
    }

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

    /**
     * 转换成SAP JSON格式数据
     * @param sapPurchase
     * @return
     */
    public String getSapPurchaseVoJson(SapPurchase sapPurchase){
        List<SapPurchaseItem> sapPurchaseItemList = this.sapPurchaseItemApplication.findBySapPurchaseId(sapPurchase.getId());
        List<SapPurchaseVo> sapPurchaseVoList = new ArrayList<>();
        sapPurchaseItemList.forEach(sapPurchaseItem -> {
            SapPurchaseVo sapPurchaseVo = new SapPurchaseVo();
            BeanUtil.copyProperties(sapPurchaseItem,sapPurchaseVo);
            sapPurchaseVo.setBillCode(sapPurchase.getBillCode());
            sapPurchaseVo.setBsart(sapPurchase.getBsart());
            sapPurchaseVoList.add(sapPurchaseVo);
        });
        ObjectMapper objectMapper = new ObjectMapper();
        String returnJson = null;
        try {
            returnJson = objectMapper.writeValueAsString(sapPurchaseVoList);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return returnJson;
    }

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

    /**
     * @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();
            SapPurchase sapPurchase = sapPurchaseRepository.findOne(bizId);
            sapPurchase.setStatusId(BizBillStatus.APPLYING.getId());
            sapPurchaseRepository.save(sapPurchase);
        }
    }

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

    @Override
    public SapPurchase loadSapPurchase(String id) {
        return sapPurchaseRepository.findOne(id);
    }
}
