/**********************************************************************
 * 
 *
 * @url: /services/apexrest/rest
 * @data:
 *  {
        
    }
*************************************************************************/
@RestResource(urlMapping='/NFM212/*')
global with sharing class NFM212Rest {

    global class GeDatasRest {
        public GeDatas GeDatas;
    }

    //定义Monitoring + header
    global class GeDatas{
        public NFMUtil.Monitoring Monitoring;
        public Header[] Header;
    }

    //定义固定折扣header
    global class Header{

        //SFDC一个表  SPO两个表 需要拼接ID 未确认
        public String SpoID;                    //固定折扣ID（SPO）
        public String DealerNo;                 //经销商管理编码
        public String ContractNo;               //经销商协议编码
        public String DateFrom;                 //有效期（从）
        public String DateTo;                   //有效期（至）
        public String DealerType;               //经销商分类
        public String DepartmentClass;          //科室
        public String ProductClass;             //产品
        public Decimal GuaranteeDiscount;       //对象品折扣
        public Decimal Discount;                //非对象品折扣
        public String Area;                     //申请区域
        public String Province;                 //省
        public String ApplyStatus;              //审批状态


    }

    @HttpPost
    global static void execute() {
        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatas ges = (GeDatas) JSON.deserializeStrict(strData, GeDatas.class);
        // GeDatas ges =gesRest.GeDatas;
        if (ges == null ) {
            return;
        }

        NFMUtil.Monitoring Monitoring = ges.Monitoring;
        if (Monitoring == null) {
            return;
        }

        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM212', ges.Header);
        if (String.isBlank(rowData.Log__c) == false) {
            executefuture(rowData.Id);
        }
        // JSONを戻す
        RestResponse res = RestContext.response;
        res.addHeader('Content-Type', 'application/json');
        res.statusCode = 200;
        //String jsonResponse = '{"status": "Success", "Message":'  + gedata + '}';
        String jsonResponse = '{"status": "Success", "Message":""}';
        res.responseBody = blob.valueOf(jsonResponse);
        return;
    }
    @future
    global static void executefuture(String rowData_Id) {
        main(rowData_Id);
    }

    global static void main(String rowData_Id) {

        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        BatchIF_Log__c rowData = [Select Id, Name, Log__c, ErrorLog__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c, Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c, MessageGroupNumber__c,retry_cnt__c from BatchIF_Log__c where RowDataFlg__c = true and Type__c='NFM212' and Id = :rowData_Id];
        String logstr = rowData.MessageGroupNumber__c + ' start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'NFM212';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;

        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<Header> geDataList = (List<Header>) JSON.deserialize(rowDataStr, List<Header>.class);
        if (geDataList == null || geDataList.size() == 0) {
            return;
        }
        //检索促销方案记录类型，并制作map
        Map<String,String> recordTypeMap = new Map<String,String>();
        if(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('Promotion').getRecordTypeId()!=null){
            recordTypeMap.put('促销政策',String.valueOf(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('Promotion').getRecordTypeId()));
        }
        if(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('NormalProduct').getRecordTypeId()!=null){
            recordTypeMap.put('促销价格产品',String.valueOf(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('NormalProduct').getRecordTypeId()));
        }
        if(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('Authorizer').getRecordTypeId()!=null){
            recordTypeMap.put('固定价格',String.valueOf(Schema.SObjectType.PromotionHead__c.getRecordTypeInfosByDeveloperName().get('Authorizer').getRecordTypeId()));
        }
        //head 必填验证 如果有则不生成数据
        Map<String,String> skippedMap = new Map<String,String>();

        //定义固定折扣Id List
        List<String> spoIdList = new List<String>();
        //构建固定折扣map,key：spoid+Category value:PromotionHead__c
        Map<String,PromotionHead__c> pHMaps = new Map<String,PromotionHead__c>();
        Savepoint sp = Database.setSavepoint();
        try{
            //检索经销商 并赋值
            List<String> dealerNoList = new List<String>();
            //验证必填
            for (Header gda :geDataList) {
                //转成json串
                String jsonStr = JSON.serialize(gda);
                system.debug('jsonStr:'+jsonStr);
                //按字段拆分 存入map key value 公共参数 因为value值类型不同 无法定义
                Map<String,Object>  headMap = (Map<String,Object>) JSON.deserializeUntyped(jsonStr);
                system.debug('headMap:'+headMap);
                /**
                 * 验证代码优化 wql 2021/10/27 start
                 * param1：已知必填字段
                 * param2：所有字段map
                 */
                //列举一部分 无条件判断的必填  写死是因为 接口文档一般会给出哪些字段必填
                // List<String> checkList =new List<String>{'SpoID','PromotionNo', 'IfContainsGuarantee', 'IsCheckProductCount', 'Price','Description','Memo'};
                // for(Integer i=0;i<checkList.size();i++){
                //     //这里需要转一下 因为肯定所有的字段类型不一样 最好用SObject
                //     if(headMap.get(checkList[i])==null){
                //         //存入必填报错信息
                //         checkSkipped(skippedMap,checkList[i],headMap,iflog);
                //         continue;
                //     }
                // }
                //先拼接key
                if(String.isNotBlank(gda.SpoID)){
                    spoIdList.add(gda.SpoID);
                }
                //验证必填字段
                //SPOId
                if(String.isBlank(gda.SpoID)){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'SpoID',headMap,iflog);
                    continue;
                }
                //经销商管理编码 必填验证
                if(String.isBlank(gda.DealerNo)){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'DealerNo',headMap,iflog);
                    continue;
                }else{
                    dealerNoList.add(gda.DealerNo);
                }
                //check start
                //经销商协议编码 必填验证
                if(String.isBlank(gda.ContractNo)){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'ContractNo',headMap,iflog);
                    continue;
                }
                //固定折扣有效期从 必填验证
                if(gda.DateFrom ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'DateFrom',headMap,iflog);
                    continue;
                }
                //固定折扣有效期至 必填验证
                if(gda.DateTo ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'DateTo',headMap,iflog);
                    continue;
                }
                //经销商分类 必填验证
                if(gda.DealerType ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'DealerType',headMap,iflog);
                    continue;
                }
                //对象品折扣 必填验证
                if(gda.GuaranteeDiscount ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'GuaranteeDiscount',headMap,iflog);
                    continue;
                }
                //非对象品折扣 必填验证
                if(gda.Discount ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'Discount',headMap,iflog);
                    continue;
                }
                //审批状态 必填验证
                if(gda.ApplyStatus ==null){
                    //存入必填报错信息
                    checkSkipped(skippedMap,'ApplyStatus',headMap,iflog);
                    continue;
                }
            //check end
            }
            
            Map<String,String> agencyMap = new Map<String,String>();
            Map<Id,String> agencyIdMap = new Map<Id,String>();

            List<PromotionHead__c> promotionHeadList = new List<PromotionHead__c>();
            //临时 的upsertList
            List<PromotionHead__c> upSertTempPromotionHeadList = new List<PromotionHead__c>();
            //最终的upsertList
            List<PromotionHead__c> upSertPromotionHeadList = new List<PromotionHead__c>();
            if(spoIdList.size()>0){
                //Query 根据接口的SpoId检索所有固定折扣
                promotionHeadList = [Select id,SpoId__c,Province__c,ProductClass__c,Area__c,NormalDiscount__c,Department__c
                                    ,Category__c,Memo__c,Description__c,Status__c,DateTo__c,DateFrom__c
                                    ,Contract__c,ApplyStatus__c,GuaranteeDiscount__c,Agency__c,DealerNo__c  from PromotionHead__c where SpoId__c=:spoIdList];

                if(promotionHeadList.size()>0){
                    for(PromotionHead__c p : promotionHeadList){
                        pHMaps.put(p.SpoId__c, p);
                       
                    }
                }
                if(dealerNoList.size()>0){
                    List<Account>  accList= [select id,Name,Management_FormulaCode__c from Account where Management_FormulaCode__c in:dealerNoList];
                    if(accList.size()>0){
                        for(Account acc : accList){
                            agencyMap.put(acc.Management_FormulaCode__c, acc.Id);
                            agencyIdMap.put(acc.Id, acc.Name);
                        }    
                    }
                }
                //生成固定折扣主数据
                for(Header infoH :geDataList){
                    PromotionHead__c tempPromotionHead = pHMaps.get(infoH.SpoID);
                    System.debug('218:'+pHMaps.get(infoH.SpoID));
                    if(infoH.SpoID!=null){
                        if(tempPromotionHead==null){
                            tempPromotionHead = new PromotionHead__c();
                            tempPromotionHead = SetPromotionHead(tempPromotionHead,infoH,recordTypeMap,agencyMap,agencyIdMap);
                            checkPH( tempPromotionHead, upSertTempPromotionHeadList, iflog, infoH );
                        }else{
                            tempPromotionHead = SetPromotionHead(tempPromotionHead,infoH,recordTypeMap,agencyMap,agencyIdMap);
                            checkPH( tempPromotionHead, upSertTempPromotionHeadList, iflog, infoH );
                        }

                    }
                }
                

            }
            //存放 spoid,主数据id
            Map<String,String>  pHeadMap= new Map<String,String>();
            System.debug('skippedMap:'+skippedMap);
            System.debug('upSertTempPromotionHeadList1:'+upSertTempPromotionHeadList);
            if (upSertTempPromotionHeadList.size() > 0) {
                //判断需要更新的list中是否有head头必填报错的数据 有则不需要生成
                for(PromotionHead__c prom:upSertTempPromotionHeadList){
                    if(!skippedMap.containsKey(prom.SpoId__c)){
                        upSertPromotionHeadList.add(prom);
                    }
                }
                system.debug('upSertPromotionHeadList'+upSertPromotionHeadList);
                //正常更新
                if(upSertPromotionHeadList.size() > 0){
                    upsert upSertPromotionHeadList ;
                }
                
            }
            logstr += '\nend';
            rowData.retry_cnt__c=0;

        }catch(Exception ex){
            Database.rollback(sp);
              System.debug(Logginglevel.ERROR, 'NFM212_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
              System.debug(Logginglevel.ERROR, 'NFM212_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
              logstr += '\n' + ex.getMessage();
              iflog.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + iflog.ErrorLog__c;

              if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
              if (rowData.retry_cnt__c < batch_retry_max_cnt) {
                  rowData.retry_cnt__c++;
                  LogAutoSendSchedule.assignOneMinute();
              }
              if (rowData.retry_cnt__c >= batch_retry_max_cnt) {
                  rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c+'错误次数已经超过自动收信设定的最大次数，请手动收信';
              }
        }



        update rowData;
        iflog.Log__c = logstr;
        if (iflog.Log__c.length() > 131072) {
            iflog.Log__c = iflog.Log__c.subString(0, 131065) + ' ...';
        }
        if (iflog.ErrorLog__c.length() > 32768) {
            iflog.ErrorLog__c = iflog.ErrorLog__c.subString(0, 32760) + ' ...';
        }
        update iflog;
    }
    /* 构建固定折扣：
     * iflog 写日志
     * infoH 为 211接口数据
     * Map<String,String> recordTypeMap 记录类型
     */
    @TestVisible
    private static PromotionHead__c SetPromotionHead(PromotionHead__c tempPH,Header infoH,Map<String,String> recordTypeMap,Map<String,String> agencyMap,Map<Id,String> agencyIdMap){
        //SPOId
        if(String.isNotBlank(infoH.SpoID)){
            tempPH.SpoId__c = infoH.SpoID;
        }
        //名称 格式待确认
        tempPH.name = infoH.SpoId;
        //记录类型
        tempPH.recordTypeid  = recordTypeMap.get('固定价格');
        //审批状态
        tempPH.ApplyStatus__c = infoH.ApplyStatus;
        //经销商管理编码 
        if(String.isNotBlank(infoH.DealerNo)){
            tempPH.DealerNo__c = infoH.DealerNo;
            if(agencyMap!=null){
                tempPH.Agency__c = agencyMap.get(infoH.DealerNo);
            }
            String tempName = agencyIdMap.get(tempPH.Agency__c)+infoH.DepartmentClass;
            if(tempName.length()>80){
                tempPH.name = tempName.substring(0, 80);
            }else{
                tempPH.name = tempName;
            }
            
        }
        //经销商协议编码 
        if(String.isNotBlank(infoH.ContractNo)){
            tempPH.Contract__c = infoH.ContractNo;
        }
        //固定折扣有效期从 
        if(infoH.DateFrom !=null){
            tempPH.DateFrom__c = NFMUtil.parseStr2Date(infoH.DateFrom);
        }
        //固定折扣有效期至 
        if(infoH.DateTo !=null){
            tempPH.DateTo__c = NFMUtil.parseStr2Date(infoH.DateTo);
        }
        //经销商分类 
        if(infoH.DealerType !=null){
            tempPH.Category__c = infoH.DealerType;
        }
        //对象品折扣 
        if(infoH.GuaranteeDiscount !=null){
            tempPH.GuaranteeDiscount__c = infoH.GuaranteeDiscount;
        }
        //非对象品折扣 
        if(infoH.Discount !=null){
            tempPH.NormalDiscount__c = infoH.Discount;
        }
        //科室
        if(infoH.DepartmentClass !=null){
            tempPH.Department__c = infoH.DepartmentClass;
        }
        //申请区域
        if(infoH.Area !=null){
            tempPH.Area__c = infoH.Area;
        }
        //省
        if(infoH.Province !=null){
            if(infoH.Province.indexOf(';')>-1){
                tempPH.Province__c = infoH.Province.substring(infoH.Province.indexOf(';')+1,infoH.Province.length());
            }else{
                tempPH.Province__c = infoH.Province;
            }
        }
        //产品
        if(infoH.ProductClass !=null){
            tempPH.ProductClass__c = infoH.ProductClass;
        }

        return tempPH;
    }
    /* 构建固定折扣List：UpsertPHList
     * 临时促销政策：tempPH
     * 日志内容：iflog
     * 接口数据：infoH
     */
    private static void checkPH(PromotionHead__c tempPH,
                                List<PromotionHead__c> UpsertPHList,
                                BatchIF_Log__c iflog,
                                Header infoH ) {
                                    if (infoH.SpoID != null){
                                        if(tempPH.Agency__c!=null){
                                            UpsertPHList.add(tempPH);
                                        }else{
                                            iflog.ErrorLog__c += 'warning! DealerNo[' + infoH.DealerNo +
                                            '] DealerNo的经销商SFDC不存在  NotExist.\n';
                                        }
                                        
                                    }else {
                                        iflog.ErrorLog__c += 'warning! SpoID[' + infoH.SpoID +
                                            '] SpoID  NotExist. The insert of this PromotionHead__c is skipped.\n';
                                    }

                                }
    /* 构建必填验证map：skippedMap
     * 字段名：key
     * 1条数据的字段拆分：headMap
     * 日志：iflog
     */
    private static void checkSkipped(Map<String,String> skippedMap,String key,Map<String,Object>  headMap,BatchIF_Log__c iflog) {
                             iflog.ErrorLog__c += 'SPOID:'+headMap.get('SpoID')+'--'+key+'[ '+ headMap.get(key) +' ] of BPType is required,This data is skipped.\n';
                                //如果SPOID为空 直接报错，所有数据无法执行；如果分类为空，只有此条数据不执行，其他正常执行。
                                skippedMap.put(String.valueOf(headMap.get('SpoID')), iflog.ErrorLog__c);
                                }
}