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.context.Operator;
import com.huigou.context.OrgUnit;
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.purchase.domain.SapPurchaseItem;
import com.huigou.topsun.sap.purchaseApproval.domain.SapPurchaseApproval;
import com.huigou.topsun.sap.purchaseApproval.domain.SapPurchaseApprovalItem;
import com.huigou.topsun.sap.sapApplication.application.SapDictionaryApplication;
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.bmp.opm.domain.model.org.Org;
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.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
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;
    @Autowired
    private SapDictionaryApplication sapDictionaryApplication;

    @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();
        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);
        this.sendSapData(stockTransfers);
    }

    @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(SapStockTransfers 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());
            sapStockTransfersItemVO.setBanfn(stockTransfers.getBanfn());//采购申请号放行项目
            newItemList.add(sapStockTransfersItemVO);
        }
        sapStockTransfersVO.setItem(newItemList);
        ObjectMapper objectMapper = new ObjectMapper();
        String url = "cud_po_zub/po_zub";
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("businessType", "存货转移数据");
        resultMap.put("businessId", stockTransfers.getId());
        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())) {
                resultMap.put("TYPE", sapResult.getTYPE());
                resultMap.put("MESSAGE", sapResult.getMESSAGE());
                stockTransfers.setType(sapResult.getTYPE());
                stockTransfers.setMessage(sapResult.getMESSAGE_V1());
                sapStockTransfersRepository.save(stockTransfers);
            } 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);
        }
    }

    /**
     * 创建存货转移单
     * @param sapPurchaseItemList
     */
    @Override
    public void createSapStockTransfersFromPurchaseApproval(SapPurchaseApproval sapPurchaseApproval, List<SapPurchaseApprovalItem> sapPurchaseItemList){
        SapStockTransfers sapStockTransfers=new SapStockTransfers();
        sapStockTransfers.setStatusId(BizBillStatus.COMPLETED.getId());
        Org org = orgApplication.loadOrgByFullId(sapPurchaseApproval.getFullId());
        sapStockTransfers.setDefaultValues(new OrgUnit(sapPurchaseApproval.getFullId(), org.getFullName()));
        sapStockTransfers.setBanfn(sapPurchaseApproval.getBanfn());
        SapPurchaseApprovalItem sapPurchaseItemFirst = sapPurchaseItemList.get(0);
        sapStockTransfers.setBsart("ZUB");
        sapStockTransfers.setLifnr(sapPurchaseItemFirst.getReswk());//供货工厂
        String text = this.getDictionaryText("WERKS", sapPurchaseItemFirst.getReswk(), "NAME1");
        sapStockTransfers.setLifnrName(text);
        sapStockTransfers.setWerks(sapPurchaseItemFirst.getWerks());//收货工厂
        String WerksName = this.getDictionaryText("WERKS", sapPurchaseItemFirst.getWerks(), "NAME1");
        sapStockTransfers.setWerksName(WerksName);
        sapStockTransfers.setEkorg("1000");//采购组织
        sapStockTransfers.setEkorgName("广州宝绅科技采购组织");
        sapStockTransfers.setBurks("1000");//公司代码
        sapStockTransfers.setBurksName("广州市宝绅科技应用有限公司");
        sapStockTransfers.setEkgrp(sapPurchaseItemFirst.getEkgrp());//采购组
        sapStockTransfers.setEkgrpName(sapPurchaseItemFirst.getEknam());
        sapStockTransfersRepository.save(sapStockTransfers);
        List<SapStockTransfersItem> itemList = new ArrayList<>();
        for (int i = 1; i <= sapPurchaseItemList.size(); i++) {
            SapPurchaseApprovalItem sapPurchaseItem = sapPurchaseItemList.get(i-1);
            SapStockTransfersItem sapStockTransfersItem=new SapStockTransfersItem();
            sapStockTransfersItem.setTransfersId(sapStockTransfers.getId());
            sapStockTransfersItem.setEpstp("U");//项目类别
            sapStockTransfersItem.setEbelp(Integer.parseInt(sapPurchaseItem.getBnfpo()));//项目编号
            sapStockTransfersItem.setMatnr(sapPurchaseItem.getMatnr());
            sapStockTransfersItem.setMenge(sapPurchaseItem.getMenge());
            sapStockTransfersItem.setMeins(sapPurchaseItem.getMeins());
            sapStockTransfersItem.setEeind(sapPurchaseItem.getLfdat());//交货日期
            sapStockTransfersItem.setLgort(sapPurchaseItem.getLgort());
            sapStockTransfersItem.setLgortName(sapPurchaseItem.getLgobe());
            sapStockTransfersItem.setMatnrName(sapPurchaseItem.getTxz01());
            sapStockTransfersItem.setMeinsName(sapPurchaseItem.getMsehl());
            itemList.add(sapStockTransfersItem);
        }
        this.sapStockTransfersItemApplication.saveSapStockTransfersItems(sapStockTransfers.getId(),itemList);

        //调用sap接口
        this.sendSapData(sapStockTransfers);
    }

    /**
     * 获取描述
     * @param fieldName  字典字段名
     * @param filterValue 筛选条件
     * @param code 描述对应的key
     * @return
     */
    public String getDictionaryText(String fieldName, String filterValue, String code){
        String text = "";
        try {
            List<Map<String, String>> mapList = sapDictionaryApplication.getSapDictionary(fieldName);
            List<String> textList = mapList
                    .stream()
                    .filter(map -> map.values().stream().anyMatch(value->value.contains(filterValue)))
                    .map(map ->{
                        return map.get(code);
                    })
                    .collect(Collectors.toList());
            text = textList.get(0);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return text;
    }
}
