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


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.topsun.sap.statsIndicators.application.SapStatsIndicatorsApplication;
import com.huigou.topsun.sap.statsIndicators.domain.SapStatsIndicators;
import com.huigou.topsun.sap.statsIndicators.domain.SapStatsIndicatorsDetail;
import com.huigou.topsun.sap.statsIndicators.domain.query.SapStatsIndicatorsDetailQueryRequest;
import com.huigou.topsun.sap.statsIndicators.domain.query.SapStatsIndicatorsQueryRequest;
import com.huigou.topsun.sap.statsIndicators.repository.SapStatsIndicatorsDetailRepository;
import com.huigou.topsun.sap.statsIndicators.repository.SapStatsIndicatorsRepository;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;

import com.huigou.util.SDO;
import lombok.SneakyThrows;
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 org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


import java.util.List;
import java.util.Map;

@Service("sapStatsIndicatorsApplication")
public class SapStatsIndicatorsApplicationImpl  extends FlowBroker implements SapStatsIndicatorsApplication {

    @Autowired
    private SapStatsIndicatorsRepository sapStatsIndicatorsRepository;
    @Autowired
    private SapStatsIndicatorsDetailRepository sapStatsIndicatorsDetailRepository;


    @SneakyThrows
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();

        SapStatsIndicators sapStatsIndicators = getBizEntity(SapStatsIndicators.class);
        if (sapStatsIndicators.isNew()) {
            sapStatsIndicators.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            sapStatsIndicators = (SapStatsIndicators) commonDomainService.loadAndFillinProperties(sapStatsIndicators);
        }
        sapStatsIndicators = sapStatsIndicatorsRepository.save(sapStatsIndicators);

        SDO sdo = this.getBizAndApprovalData();
        String statsIndicatorsDetailJSON = sdo.getString("statsIndicatorsDetail");
        ObjectMapper objectMapper = new ObjectMapper();
        List<SapStatsIndicatorsDetail> statsIndicatorsDetailList = objectMapper.readValue(statsIndicatorsDetailJSON, new TypeReference<List<SapStatsIndicatorsDetail>>() {});

        List<SapStatsIndicatorsDetail> allStatsIndicatorsDetail = sapStatsIndicatorsDetailRepository.findAllByStatsIndicatorsId(sapStatsIndicators.getId());
        if (!allStatsIndicatorsDetail.isEmpty()) {
            sapStatsIndicatorsDetailRepository.deleteInBatch(allStatsIndicatorsDetail);
        }
        for (SapStatsIndicatorsDetail statsIndicatorsDetail : statsIndicatorsDetailList) {
            statsIndicatorsDetail.setStatsIndicatorsDetailId(null);
            statsIndicatorsDetail.setStatsIndicatorsId(sapStatsIndicators.getId());
            sapStatsIndicatorsDetailRepository.save(statsIndicatorsDetail);
        }
        return sapStatsIndicators.getId();
    }


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

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

        //远程调用sap接口
        List<SapStatsIndicatorsDetail> all = sapStatsIndicatorsDetailRepository.findAllByStatsIndicatorsId(bizId);


    }

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

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

    @Override
    public SapStatsIndicators loadSapStatsIndicatorsById(String id) {
        return sapStatsIndicatorsRepository.findOne(id);
    }

    @Override
    public Map<String, Object> slicedStatsIndicatorsQuery(SapStatsIndicatorsQueryRequest query) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedStatsIndicatorsQuery");
        return this.sqlExecutorDao.executeSlicedQuery(queryDescriptor,query);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void deleteStatsIndicatorsById(String id) {
        List<SapStatsIndicatorsDetail> all = sapStatsIndicatorsDetailRepository.findAllByStatsIndicatorsId(id);
        sapStatsIndicatorsDetailRepository.deleteInBatch(all);
        sapStatsIndicatorsRepository.delete(id);

    }

    @Override
    @Transactional
    public void deleteStatsIndicatorsByIds(List<String> ids) {
        ids.forEach(this::deleteStatsIndicatorsById);
    }
}