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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huigou.cache.DictUtil;
import com.huigou.cache.SystemCache;
import com.huigou.context.Operator;
import com.huigou.context.ThreadLocalUtil;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.data.query.model.QueryModel;
import com.huigou.topsun.base.bsnMessage.appliction.BsnMessageApplication;
import com.huigou.topsun.base.bsnMessage.domain.ActiveStatus;
import com.huigou.topsun.base.bsnMessage.domain.BsnMessageExecute;
import com.huigou.topsun.base.bsnMessage.domain.BsnMessageSponsor;
import com.huigou.topsun.sap.clientMaterials.application.ClientMaterialsApplication;
import com.huigou.topsun.sap.clientMaterials.domain.ClientMaterials;
import com.huigou.topsun.sap.clientMaterials.domain.query.ClientMaterialsQueryRequest;
import com.huigou.topsun.sap.clientMaterials.repository.ClientMaterialsRepository;
import com.huigou.topsun.sap.clientMaterials.vo.ClientMaterialsQueryRequestVo;
import com.huigou.topsun.sap.clientMaterials.vo.ClientMaterialsVo;
import com.huigou.topsun.sap.common.HttpClient;
import com.huigou.topsun.sap.common.domain.SapResult;
import com.huigou.topsun.sap.nonProdApply.application.NonProdApplyDeptApplication;
import com.huigou.topsun.util.SAPUtils;
import com.huigou.uasp.bmp.common.application.BaseApplication;
import com.huigou.uasp.bmp.opm.application.OrgApplication;
import com.huigou.uasp.bmp.opm.domain.model.org.Org;
import com.huigou.util.ClassHelper;
import com.huigou.util.JSONUtil;
import com.huigou.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: Lxh
 * @Date: 2024/06/05/11:35
 * @Description:
 */
@Service("clientMaterialsApplication")
public class ClientMaterialsApplicationImpl extends BaseApplication implements ClientMaterialsApplication {
    @Autowired
    private ClientMaterialsRepository clientMaterialsRepository;
    @Autowired
    private HttpClient httpClient;
    @Autowired
    private OrgApplication orgApplication;
    @Autowired
    BsnMessageApplication bsnMessageApplication;
    @Autowired
    private NonProdApplyDeptApplication nonProdApplyDeptApplication;


    @Override
    public Map<String, Object> getClientMaterialsList(ClientMaterialsQueryRequest queryRequest) {
        //先从SAP获取数据
        this.getClientMaterialsListFromSap(queryRequest);
        Map<String, Object> map = new HashMap<>();
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "clientMaterials");
        QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
        queryModel.putDictionary("closed", DictUtil.getDictionary("yesorno"));
        map = this.sqlExecutorDao.executeSlicedQuery(queryModel);
        //如果是查询已关单的数据，从bpm获取数据
//        if ("1".equals(queryRequest.getClosed())){
//            QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "clientMaterials");
//            QueryModel queryModel = this.sqlExecutorDao.getQueryModel(queryDescriptor, queryRequest);
//            queryModel.putDictionary("closed", DictUtil.getDictionary("yesorno"));
//            map = this.sqlExecutorDao.executeSlicedQuery(queryModel);
//        }else {
//            map = this.getClientMaterialsListFromSap(queryRequest);
//        }
        return map;
    }

    @Override
    public Map<String, Object> getClientMaterialsListFromSap(ClientMaterialsQueryRequest queryRequest) {
        List<ClientMaterialsVo>  sapClientMaterialsList = new ArrayList<>();
        Map<String, Object> dataMap = new HashMap<>();
        ClientMaterialsQueryRequestVo queryRequestVo = new ClientMaterialsQueryRequestVo();
        ClassHelper.copyProperties(queryRequest,queryRequestVo);
        ArrayList<Map<String, Object>> maps = new ArrayList<>();
        String json = null;
        try {
            //http://192.168.3.109:8000/sap/bc/erp_ep/search/sch_planorder?sap-client=300
            json = httpClient.execute(queryRequestVo, "search/sch_planorder");
            Map<String, Object> map = JSONUtil.toMap(json);
            SapResult sapResult = JSONObject.parseObject(JSONUtil.toString(map.get("MSG")), SapResult.class);
            if ("S".equals(sapResult.getTYPE())){
                ObjectMapper objectMapper = SAPUtils.objectMapper();
                //忽略不存在
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                //忽略大小写
                objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
                sapClientMaterialsList = objectMapper.readValue(JSONUtil.toString(map.get("RDATA")), new TypeReference<List<ClientMaterialsVo>>() {});
                //保存数据到数据库留档，防止SAP跑MRP后删除计划订单的情况
                this.saveClientMaterials(sapClientMaterialsList);
                maps = objectMapper.convertValue(sapClientMaterialsList, new TypeReference<ArrayList<Map<String, Object>>>() {
                });
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        dataMap.put("Rows",maps);
        return dataMap;
    }

    public void saveClientMaterials(List<ClientMaterialsVo> sapClientMaterialsList){
        //根据计划订单查询，如果没有就新增，有就修改
        for (ClientMaterialsVo clientMaterialsVo : sapClientMaterialsList) {
            //ClientMaterials clientMaterialsDb = clientMaterialsRepository.findByPlnum(clientMaterialsVo.getPlnum());
            List<ClientMaterials> clientMaterialsDbs = clientMaterialsRepository.findByPlnumAndKdaufAndKdpos(clientMaterialsVo.getPlnum(),clientMaterialsVo.getKdauf(),clientMaterialsVo.getKdpos());
            if (CollectionUtils.isEmpty(clientMaterialsDbs)){
                QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "queryPersonByRole");
                List<Map<String, Object>> personMaps = this.sqlExecutorDao.queryToListMap(queryDescriptor.getSql(), null);
                ClientMaterials clientMaterialsDb = new ClientMaterials();
                BeanUtil.copyProperties(clientMaterialsVo,clientMaterialsDb);
                //根据跟单员初始化创建人信息
                String partner = clientMaterialsVo.getPartner();
                if (StringUtil.isNotBlank(partner)){
                    //去掉前导0
                    String replacedCode = partner.replaceFirst("^0*", "");
                    Org org = orgApplication.loadMainOrgByLoginName(replacedCode);
                    String acceptPersonCode = SystemCache.getParameter("acceptPersonCode", String.class);
                    if (ObjectUtil.isNull(org)){
                        org = orgApplication.loadMainOrgByLoginName(acceptPersonCode);
                    }
                    if (ObjectUtil.isNotNull(org)){
                        clientMaterialsDb.setPersonMemberId(org.getId());
                        clientMaterialsDb.setPersonMemberName(org.getName());
                        clientMaterialsDb.setFullId(org.getFullId());
                    }else {
                        clientMaterialsDb.setFullId(partner);
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("id",org.getPerson().getId());
                    personMaps.add(map);
                }

                //根据物料编码查询客户名称
                if (StringUtils.isNotBlank(clientMaterialsVo.getMatnr())){
                    String kunnrName = nonProdApplyDeptApplication.queryKunnrNameByMatnr(clientMaterialsVo.getMatnr());
                    clientMaterialsDb.setKunnrName(kunnrName);
                }
                clientMaterialsRepository.save(clientMaterialsDb);

                //推送待办任务
                this.pushTask(clientMaterialsDb,personMaps);
            }else {
                for (ClientMaterials clientMaterialsDb : clientMaterialsDbs) {
                    //不为空，更新数据
                    BeanUtil.copyProperties(clientMaterialsVo,clientMaterialsDb);
                    //根据物料编码查询客户名称
                    if (StringUtils.isNotBlank(clientMaterialsVo.getMatnr()) && StringUtil.isBlank(clientMaterialsDb.getKunnrName())){
                        String kunnrName = nonProdApplyDeptApplication.queryKunnrNameByMatnr(clientMaterialsVo.getMatnr());
                        clientMaterialsDb.setKunnrName(kunnrName);
                    }
                    clientMaterialsRepository.save(clientMaterialsDb);
                }
            }
        }

        //删除已关单的数据
        List<ClientMaterials> clientMaterialsList = clientMaterialsRepository.findAll();
        Set<String> plnumSet = sapClientMaterialsList.stream()
                .map(ClientMaterialsVo::getPlnum)
                .collect(Collectors.toSet());

        List<ClientMaterials> materialsList = clientMaterialsList.stream()
                .filter(obj ->StringUtil.isBlank(obj.getClosed()))
                .filter(obj -> !plnumSet.contains(obj.getPlnum()))
                .collect(Collectors.toList());
        //标记已删除
        if (!CollectionUtils.isEmpty(materialsList)){
            materialsList
                    .stream()
                    .forEach(obj -> {
                        obj.setClosed("1");
                        clientMaterialsRepository.save(obj);
                    });
        }
    }

    @Override
    public ClientMaterials getClientMaterialsById(String id) {
        return clientMaterialsRepository.findOne(id);
    }

    @Override
    public void deleteFromSap(ClientMaterials clientMaterials) {
        Map<String, Object> map = new HashMap<>();
        map.put("PLANNEDORDER",clientMaterials.getPlnum());
        //http://192.168.3.109:8000/sap/bc/erp_ep/del_planorder?sap-client=300
        String json = null;
        try {
            //http://192.168.3.109:8000/sap/bc/erp_ep/del_planorder?sap-client=300
            json = httpClient.execute(map,"del_planorder");
            Map<String, Object> resultMap = JSONUtil.toMap(json);
            SapResult sapResult = JSONObject.parseObject(JSONUtil.toString(resultMap.get("MSG")), SapResult.class);
            if ("S".equals(sapResult.getTYPE()) || sapResult.getMESSAGE().contains("不存在")){
                //删除成功，保存数据
                clientMaterials.setClosed("1");
                clientMaterialsRepository.save(clientMaterials);
                bsnMessageApplication.deleteByBusinessId(clientMaterials.getId());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void pushTask(ClientMaterials clientMaterialsDb, List<Map<String, Object>> personMaps){
        BsnMessageSponsor bsnMessageSponsor = new BsnMessageSponsor();
        //通过角色“客供料通知角色”查询通知人员
        for (Map<String, Object> map : personMaps) {
            bsnMessageSponsor.setTaskSponsor(map.get("id").toString());
            bsnMessageSponsor.setTitle(clientMaterialsDb.getPlnum());
            bsnMessageSponsor.setExecutorUrl("clientMaterials/forwardClientMaterialsList.do?plnum="+clientMaterialsDb.getPlnum()+"&isReadOnly=false");
            bsnMessageSponsor.setBusinessId(clientMaterialsDb.getId());
            bsnMessageSponsor.setCreateDate(new Date());
            bsnMessageSponsor.setStatus(0);
            bsnMessageApplication.saveBsnMessageSponsor(bsnMessageSponsor);

            //保存任务执行人
            List<BsnMessageExecute> executes = new ArrayList<>();
            BsnMessageExecute messageExecute = new BsnMessageExecute();
            messageExecute.setMessageSponsorId(bsnMessageSponsor.getId());
            messageExecute.setTaskExecute(map.get("id").toString());
            messageExecute.setBusinessCode("clientMaterials");
            messageExecute.setActive(ActiveStatus.UNFINISHED.getValue());
            messageExecute.setUpdateDate(new Date());
            messageExecute.setTaskDescribe("通知：客供料计划订单号："+ clientMaterialsDb.getPlnum());
            executes.add(messageExecute);
            bsnMessageApplication.saveBsnMessageExecute(executes);
        }


    }

}
