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

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
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.customerDelayPay.application.CustomerDelayPayApplication;
import com.huigou.topsun.sap.customerDelayPay.application.CustomerDelayPayItemApplication;
import com.huigou.topsun.sap.customerDelayPay.domain.CustomerDelayPay;
import com.huigou.topsun.sap.customerDelayPay.domain.query.CustomerDelayPayQueryRequest;
import com.huigou.topsun.sap.customerDelayPay.repository.CustomerDelayPayRepository;
import com.huigou.topsun.sap.customerDelayPay.domain.CustomerDelayPay;
import com.huigou.topsun.sap.customerDelayPay.domain.CustomerDelayPayItem;
import com.huigou.uasp.bmp.common.BizBillStatus;
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 org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: xin.lu
 * @Date: 2024/04/13/14:50
 * @Description:
 */
@Service("customerDelayPayApplication")
public class CustomerDelayPayApplicationImpl extends FlowBroker implements CustomerDelayPayApplication {
    @Autowired
    private CustomerDelayPayRepository customerDelayPayRepository;
    
    @Autowired
    private CustomerDelayPayItemApplication customerDelayPayItemApplication;

    @Autowired
    DefaultHttpClient defaultHttpClient;
    @Override
    public CustomerDelayPay findCustomerDelayPayById(String id) {
        return customerDelayPayRepository.findOne(id);
    }

    @Override
    public CustomerDelayPay saveCustomerDelayPay(CustomerDelayPay customerDelayPay) {
        return customerDelayPayRepository.save(customerDelayPay);
    }

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

    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        CustomerDelayPay customerDelayPay = getBizEntity(CustomerDelayPay.class);
        if (customerDelayPay.isNew()) {
            customerDelayPay.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            customerDelayPay = (CustomerDelayPay) commonDomainService.loadAndFillinProperties(customerDelayPay);
        }
        customerDelayPay = customerDelayPayRepository.save(customerDelayPay);
        List<CustomerDelayPayItem> customerDelayPayItems = getBizEntities(CustomerDelayPayItem.class, "items");
        customerDelayPayItemApplication.saveCustomerDelayPayItems(customerDelayPay.getId(),customerDelayPayItems);
        return customerDelayPay.getId();
    }

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

    /**
     * 任务完成前执行
     */
    @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);
        }
    }

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

    /**
     * 流程撤销事件
     **/
    @Override
    protected void onRecallProcessInstance(DelegateExecution delegateExecution) {
        String bizId = delegateExecution.getProcessBusinessKey();
        // 修改单据状态为申请
        updateStatus(bizId, BizBillStatus.APPLYING);
    }

    /**
     * 回收事件
     **/
    @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);
        }
    }

    @Override
    protected void onEnd(DelegateExecution delegateExecution) {
        super.onEnd(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        BizBillStatus status = approvePassed() ? BizBillStatus.COMPLETED : BizBillStatus.ABORTED;
        CustomerDelayPay customerDelayPay = customerDelayPayRepository.findOne(bizId);
        customerDelayPay.setStatusId(status.getId());
        customerDelayPayRepository.save(customerDelayPay);
        this.sendCustomerDelayPayToSap(customerDelayPay);
    }

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

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

    public void sendCustomerDelayPayToSap(CustomerDelayPay customerDelayPay){
        Map<String,Object> param = new HashMap<>();
        param.put("BUKRS",customerDelayPay.getBukrs());
        param.put("KUNNR",customerDelayPay.getCustomer());
        param.put("ZBPMNR",customerDelayPay.getBillCode());
        String payDate = DateUtil.getDateFormat(customerDelayPay.getPayDate(), "yyyyMMdd");
        param.put("DATUM",payDate);
        List<Map<String,Object>> mapList = new ArrayList<>();
        mapList.add(param);
        ObjectMapper objectMapper = new ObjectMapper();
        String url = "overdue_rel";
        try {
            String result = defaultHttpClient.execute(mapList, url);
            List<Map<String, Object>> resultList = objectMapper.readValue(result, new TypeReference<List<Map<String, Object>>>() {});
            Map<String, Object> resultMap = resultList.get(0);
            if (!"S".equals(resultMap.get("TYPE"))) {
                throw new RuntimeException("数据传输失败，请稍后手动重试！"+resultMap.get("MESSAGE"));
            }
            customerDelayPay.setType((String) resultMap.get("TYPE"));
            customerDelayPay.setMessage((String) resultMap.get("MESSAGE"));
            customerDelayPayRepository.save(customerDelayPay);
        } catch (Exception e) {
            throw new RuntimeException("数据传输失败请检查数据后重试！"+e.getMessage());
        }
    }

}
