@RestResource(urlMapping='/SBG005/*')
global with sharing class SBG005Rest  {
	public class SBG005ResrException extends Exception {}
    global class GeDatasRest {
        public GeDatas GeDatas;
    }

    global class GeDatas {
        public NFMUtil.Monitoring Monitoring;
        public SBG005Rest.GeData[] GeData;
    }
    global class GeData {
        public String  ProductCode;
        public String  Currency_x;
        public String  ProductSegment;
        public String  TradeType;
        public String  MachineParts;
        public String  SalesChannel;
        public Decimal SalesPrice;
        public String  DealerDistinguish;
        public String  EffectiveDateFrom;
        public String  EffectiveDateTo;
        public String  PurposeOfAdvice;
        public String  Other1;
        public String  Other2;
        public String  Other3;
    }

    @HttpPost
    global static void execute() {

        // 取得接口传输内容
        String strData = RestContext.request.requestBody.toString();
        GeDatasRest ges = (GeDatasRest) JSON.deserializeStrict(strData, GeDatasRest.class);

        if (ges == null ) {
            return;
        }

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

        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'SBG005', ges.GeDatas.GeData);
        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 = scope[0];
        //String logstr = rowData.MessageGroupNumber__c + ' ' + startIndex + '/' + dataLength + ' start\n';
        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 Id = :rowData_Id];
        String logstr = '';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'SBG005';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        //iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<GeData> purchasePriceList2 = (List<GeData>) JSON.deserialize(rowDataStr, List<GeData>.class);
        if (purchasePriceList2 == null || purchasePriceList2.size() == 0) {
            return;
        }
        List<GeData> purchasePriceList = new List<GeData>();
        List<String> productCodeList = new List<String>();
        for (Integer i = 0; i < purchasePriceList2.size(); i++) {
            purchasePriceList.add(purchasePriceList2.get(i));
            if (String.isBlank(purchasePriceList2.get(i).ProductCode) == false) {
                productCodeList.add(purchasePriceList2.get(i).ProductCode);
            }
        }

        Map<String, Product2> prdsMap = new Map<String, Product2>();
        for (Product2 prd : [select Id, ProductCode, Product_ECCode__c,
                                         EffectiveDateTo__c,
                                         ProductModels__c,
                                         ProductStatus__c
                                    from Product2
                                   where ProductModels__c = false and ProductCode in :productCodeList]
        ) {
            prdsMap.put(prd.ProductCode, prd);
        }

        Map <String,Pricebook2 > prebookmap = new Map<String,Pricebook2 >();

        for(Pricebook2 pre : [Select Id,Name,MachineParts__c,ProductSegment__c,SalesChannel__c,TradeType__c,isActive
                                 from Pricebook2 where IsStandard = false])
        {
            prebookmap.put(pre.ProductSegment__c + '_' + pre.TradeType__c + '_' + pre.SalesChannel__c + '_' + pre.MachineParts__c,pre);
        }


        List<String> prekeys = new List<String>();
        for(GeData data : purchasePriceList2)
        {
            String salesChannel = data.SalesChannel == '41' ? 'dealer' : 'direct';
            String key = data.ProductSegment + '_' + data.TradeType + '_' + salesChannel + '_' + data.MachineParts + '_' + data.ProductCode + '_' + data.Currency_x;
            prekeys.add(key);
        }
        system.debug('=====0:' + prekeys);
        Map <String,PricebookEntry > premap = new Map<String,PricebookEntry >();
        for(PricebookEntry pre : [Select Id,Name,KEY__c,EffectiveDateFrom1__c,EffectiveDateFrom2__c,EffectiveDateTo1__c,EffectiveDateTo2__c,
                                        EffectiveDateFrom1_sales__c,EffectiveDateFrom1_sales_A__c,EffectiveDateFrom1_sales_B__c,EffectiveDateFrom1_sales_C__c,
                                        EffectiveDateFrom2_sales__c,EffectiveDateFrom2_sales_A__c,EffectiveDateFrom2_sales_B__c,EffectiveDateFrom2_sales_C__c,
                                        EffectiveDateTo1_sales__c,EffectiveDateTo1_sales_A__c,EffectiveDateTo1_sales_B__c,EffectiveDateTo1_sales_C__c,
                                        EffectiveDateTo2_sales__c,EffectiveDateTo2_sales_A__c,EffectiveDateTo2_sales_B__c,EffectiveDateTo2_sales_C__c,
                                        CostPrice1__c,CostPrice2__c,
                                        SalesPrice1__c,SalesPrice1A__c,SalesPrice1B__c,SalesPrice1C__c,
                                        SalesPrice2__c,SalesPrice2A__c,SalesPrice2B__c,SalesPrice2C__c
                                 from PricebookEntry where KEY__c in:prekeys])
        {
            premap.put(pre.KEY__c,pre);
        }

        Savepoint sp = Database.setSavepoint();
    try {
        Map<String,PricebookEntry> updPresMap = new Map<String,PricebookEntry>();
        Boolean retrycntFlag = false;
        for (Integer i = 0; i < purchasePriceList2.size(); i++) 
        {
            //purchasePriceList.add(purchasePriceList2.get(i));
            GeData data = purchasePriceList2.get(i);
            if (data.PurposeOfAdvice == '1') {
                    data.EffectiveDateTo = NFMUtil.formatDate2Str(Date.today().addDays(-1));
                }
            if (String.isBlank(purchasePriceList2.get(i).ProductCode) == false) 
            {
                //productCodeList.add(purchasePriceList2.get(i).ProductCode);
                if (data.ProductCode == null || data.ProductCode == '') {
                    iflog.ErrorLog__c += 'ProductCode is required\n';
                    continue;
                }
                if (data.ProductSegment == null || data.ProductSegment == '') {
                    iflog.ErrorLog__c += '[' + data.ProductCode + ']PriceType is required\n';
                    continue;
                }
                if (data.Currency_x == null || data.Currency_x == '') {
                    iflog.ErrorLog__c += '[' + data.ProductCode + ']Currency is required\n';
                    continue;
                }
                if (data.EffectiveDateFrom == null || data.EffectiveDateFrom == '') {
                    iflog.ErrorLog__c += '[' + data.ProductCode + ']EffectiveDateFrom is required\n';
                    continue;
                }
                if (data.EffectiveDateTo == null || data.EffectiveDateTo == '') {
                    iflog.ErrorLog__c += '[' + data.ProductCode + ']EffectiveDateTo is required\n';
                    continue;
                }
                if(prdsMap.get(data.ProductCode) == null){
                    iflog.ErrorLog__c += 'Product[' + data.ProductCode + ']NotExist\n';
                    retrycntFlag = true;
                    continue;
                }

                String salesChannel = data.SalesChannel == '41' ? 'dealer' : 'direct';
                String pbekey = data.ProductSegment + '_' + data.TradeType + '_' + salesChannel + '_' + data.MachineParts + '_' + data.ProductCode + '_' + data.Currency_x;
                String pbkey = data.ProductSegment + '_' + data.TradeType + '_' + salesChannel + '_' + data.MachineParts;
                System.debug(prdsMap.get(data.ProductCode));
                System.debug(prebookmap);
                if(!prebookmap.keyset().contains(pbkey)){
                     iflog.ErrorLog__c += 'Pricebook2[' + pbkey + ']NotExist\n';
                    continue;
                }
                if(String.isBlank(prebookmap.get(pbkey).Id))
                {
                    iflog.ErrorLog__c += 'Pricebook2[' + pbkey + ']NotExist\n';
                    continue;
                }
                System.debug('=====1:' + premap);
                PricebookEntry pre1 = setpricebookec(data,premap,prdsMap.get(data.ProductCode).Id,prebookmap.get(pbkey),pbekey,updPresMap);
                System.debug('=====2:' + pre1);


            }
        }
        logstr += 'Execute Record:' + updPresMap.keySet().size() + '\n';
        upsert(updPresMap.Values());

            logstr += '\nend';
            if (retrycntFlag) {
                LogAutoSend(rowData,batch_retry_max_cnt,iflog);
            } else {
               rowData.retry_cnt__c = 0; 
            }
        } catch(Exception ex) {
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'SBG005_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'SBG005_' + rowData.MessageGroupNumber__c + ':' + ex.getStackTraceString());
            Database.rollback(sp);
            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++;
                LogAutoSendScheduleProduct.assignOneMinute();
            }
        }
        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;
    }

    global static void LogAutoSend (BatchIF_Log__c rowData,Integer batch_retry_max_cnt,BatchIF_Log__c iflog) {
        system.debug('LogAutoSend---Start');
        if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
        
        if (rowData.retry_cnt__c < batch_retry_max_cnt){
            rowData.retry_cnt__c++;
            LogAutoSendScheduleProduct.assignOneMinute();
        }
        if (rowData.retry_cnt__c >= batch_retry_max_cnt){
            rowData.ErrorLog__c = iflog.ErrorLog__c+'错误次数已经超过自动收信设定的最大次数，请手动收信';
        }

        update rowData;

    }
    
    global static PricebookEntry setpricebookec(GeData data,Map<String,PricebookEntry> premap,String productid,Pricebook2 pricebook2,String pbekey,Map<String,PricebookEntry> updPresMap)
    {   System.debug(productid);
        Date dateFrom = NFMUtil.parseStr2Date(data.EffectiveDateFrom, false);
        Date dateTo = NFMUtil.parseStr2Date(data.EffectiveDateTo, true);
        String curr = data.Currency_x == 'RMB' ? 'CNY' : data.Currency_x;
        
        PricebookEntry pre = premap.get(pbekey);
        if(updPresMap.containsKey(pbekey))
        {
           pre = updPresMap.get(pbekey);
        }
        System.debug('=====3' + pre);
        String dea = String.isBlank(data.DealerDistinguish) ? '' : '_' + data.DealerDistinguish;
            if (pre == null){
                pre = new PricebookEntry(KEY__c =  pbekey,
                                         //SalesPrice1__c = data.SalesPrice,
                                         DealerDistinguish_del__c = data.DealerDistinguish,
                                         CurrencyIsoCode = curr,
                                         //EffectiveDateFrom1_sales__c = dateFrom,
                                         //EffectiveDateTo1_sales__c = dateTo,
                                         UnitPrice = 0,
                                         Product2Id = productid,
                                         Pricebook2id = pricebook2.Id,
                                         isActive = pricebook2.isActive,
                                         UseStandardPrice = false);   
                if(String.isNotBlank(data.DealerDistinguish)){
                    pre.put('SalesPrice1' + data.DealerDistinguish + '__c',data.SalesPrice);
                    pre.put('EffectiveDateFrom1_sales_' + data.DealerDistinguish + '__c' , dateFrom);
                    pre.put('EffectiveDateTo1_sales_' + data.DealerDistinguish + '__c',dateTo);
                }
                else{
                    pre.put('SalesPrice1__c',data.SalesPrice);
                    pre.put('EffectiveDateFrom1_sales__c' , dateFrom);
                    pre.put('EffectiveDateTo1_sales__c',dateTo);
                }

            }
            else if((Date)pre.get('EffectiveDateFrom1_sales' + dea + '__c') == null || (Date)pre.get('EffectiveDateTo1_sales' + dea + '__c') < Date.today() || (Date)pre.get('EffectiveDateFrom1_sales'+ dea + '__c') == dateFrom){
                    //pre = new PricebookEntry(KEY__c =  pbekey,
                    //                         Id = pre.Id,
                    //                         //SalesPrice1__c = data.SalesPrice,
                    //                         DealerDistinguish_del__c = data.DealerDistinguish,
                    //                         CurrencyIsoCode = curr,
                    //                         //EffectiveDateFrom1_sales__c = dateFrom,
                    //                         //EffectiveDateTo1_sales__c = dateTo,
                    //                         UnitPrice = 0,
                    //                         Product2Id = productid,
                    //                         Pricebook2id = pricebook2.Id,
                    //                         isActive = pricebook2.isActive,
                    //                         UseStandardPrice = false);
                        pre.put('Id' , pre.Id);
                        pre.put('DealerDistinguish_del__c',data.DealerDistinguish);
                        pre.put('UnitPrice',0);
                        pre.put('isActive',pricebook2.isActive);
                        pre.put('UseStandardPrice',false); 
                    if(String.isNotBlank(data.DealerDistinguish)){
                        pre.put('SalesPrice1' + data.DealerDistinguish + '__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom1_sales_' + data.DealerDistinguish + '__c' , dateFrom);
                        pre.put('EffectiveDateTo1_sales_' + data.DealerDistinguish + '__c',dateTo);
                    }
                    else{
                        pre.put('SalesPrice1__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom1_sales__c' , dateFrom);
                        pre.put('EffectiveDateTo1_sales__c',dateTo);
                    }
            }
            else if((Date)pre.get('EffectiveDateFrom2_sales' + dea + '__c') == null || (Date)pre.get('EffectiveDateTo2_sales' + dea + '__c') < Date.today() || (Date)pre.get('EffectiveDateFrom2_sales' + dea + '__c') == dateFrom){
                    //pre = new PricebookEntry(KEY__c =  pbekey,
                    //                         Id = pre.Id,
                    //                         //SalesPrice2__c = data.SalesPrice,
                    //                         DealerDistinguish_del__c = data.DealerDistinguish,
                    //                         CurrencyIsoCode = curr,
                    //                         //EffectiveDateFrom2_sales__c = dateFrom,
                    //                         //EffectiveDateTo2_sales__c = dateTo,
                    //                         UnitPrice = 0,
                    //                         Product2Id = productid,
                    //                         Pricebook2id = pricebook2.Id,
                    //                         isActive = pricebook2.isActive,
                    //                         UseStandardPrice = false);   
                        pre.put('Id' , pre.Id);
                        pre.put('DealerDistinguish_del__c',data.DealerDistinguish);
                        pre.put('UnitPrice',0);
                        pre.put('isActive',pricebook2.isActive);
                        pre.put('UseStandardPrice',false);  
                    if(String.isNotBlank(data.DealerDistinguish)){
                        pre.put('SalesPrice2' + data.DealerDistinguish + '__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom2_sales_' + data.DealerDistinguish + '__c' , dateFrom);
                        pre.put('EffectiveDateTo2_sales_' + data.DealerDistinguish + '__c',dateTo);
                    }
                    else{
                    pre.put('SalesPrice2__c',data.SalesPrice);
                    pre.put('EffectiveDateFrom2_sales__c' , dateFrom);
                    pre.put('EffectiveDateTo2_sales__c',dateTo);
                    }
            }
            else if((Date)pre.get('EffectiveDateFrom1_sales' + dea + '__c') < (Date)pre.get('EffectiveDateFrom2_sales' + dea + '__c')){
                    //pre = new PricebookEntry(KEY__c =  pbekey,
                    //                         Id = pre.Id,
                    //                         //SalesPrice1__c = data.SalesPrice,
                    //                         DealerDistinguish_del__c = data.DealerDistinguish,
                    //                         CurrencyIsoCode = curr,
                    //                         //EffectiveDateFrom1_sales__c = dateFrom,
                    //                         //EffectiveDateTo1_sales__c = dateTo,
                    //                         UnitPrice = 0,
                    //                         Product2Id = productid,
                    //                         Pricebook2id = pricebook2.Id,
                    //                         isActive = pricebook2.isActive,
                    //                         UseStandardPrice = false);  
                        pre.put('Id' , pre.Id);
                        pre.put('DealerDistinguish_del__c',data.DealerDistinguish);
                        pre.put('UnitPrice',0);
                        pre.put('isActive',pricebook2.isActive);
                        pre.put('UseStandardPrice',false); 
                    if(String.isNotBlank(data.DealerDistinguish)){
                        pre.put('SalesPrice1' + data.DealerDistinguish + '__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom1_sales_' + data.DealerDistinguish + '__c' , dateFrom);
                        pre.put('EffectiveDateTo1_sales_' + data.DealerDistinguish + '__c',dateTo);
                    }
                    else{
                        pre.put('SalesPrice1__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom1_sales__c' , dateFrom);
                        pre.put('EffectiveDateTo1_sales__c',dateTo);
                    }
            }
            else{
                    //pre = new PricebookEntry(KEY__c =  pbekey,
                    //                         Id = pre.Id,
                    //                         //SalesPrice2__c = data.SalesPrice,
                    //                         DealerDistinguish_del__c = data.DealerDistinguish,
                    //                         CurrencyIsoCode = curr,
                    //                         //EffectiveDateFrom2_sales__c = dateFrom,
                    //                         //EffectiveDateTo2_sales__c = dateTo,
                    //                         UnitPrice = 0,
                    //                         Product2Id = productid,
                    //                         Pricebook2id = pricebook2.Id,
                    //                         isActive = pricebook2.isActive,
                    //                         UseStandardPrice = false);  
                        pre.put('Id' , pre.Id);
                        pre.put('DealerDistinguish_del__c',data.DealerDistinguish);
                        pre.put('UnitPrice',0);
                        pre.put('isActive',pricebook2.isActive);
                        pre.put('UseStandardPrice',false); 
                    if(String.isNotBlank(data.DealerDistinguish)){
                        pre.put('SalesPrice2' + data.DealerDistinguish + '__c',data.SalesPrice);
                        pre.put('EffectiveDateFrom2_sales_' + data.DealerDistinguish + '__c' , dateFrom);
                        pre.put('EffectiveDateTo2_sales_' + data.DealerDistinguish + '__c',dateTo);
                    }
                    else{
                    pre.put('SalesPrice2__c',data.SalesPrice);
                    pre.put('EffectiveDateFrom2_sales__c' , dateFrom);
                    pre.put('EffectiveDateTo2_sales__c',dateTo);
                    }
                }
            updPresMap.put(pbekey,pre);
            return pre;
    }
}