public class SBG007TriggerHandler {
    public static boolean isRunning = false;
    public static String debug_msg = '';
    public static Set<Id> SBG007_Ids = new Set<Id>();
    //007修改Rest gwy start 2021-04-06
    public static String status;
    public class SBG007 {
        public GeDatas_element GeDatas;
    }

    public class GeDatas_element {
        public NFMUtil.Monitoring Monitoring;
        public GeData_element[] GeData;
    }

    public class GeData_element {
        public String SalesAccountCode;
        public String DealerCode;
        public String OpportunityCode;
        public String ProductSegment;
        public String TradeType;
        public String MachineParts;
        public String SalesChannel;
        public String ExpectedDeliveryDate;
        public String DealerSalesStaffName;  
        public String ForeignTradeCompany;   
        public String SpecialDeliveryAddress;
        public String Other1;
        public String Other2;
        public String Other3;
        public GeDataDetails_element[] GeDataDetails;
        
    }
    public class GeDataDetails_element {
        public Integer DetailLine;
        public String ItemCode;
        public Integer ItemQuantity;
    }
    //007修改Rest gwy end 2021-04-06
    public static void SBG007OpportunityTrigger(List<Opportunity> newList, Map<Id, Opportunity> newMap, List<Opportunity> oldList, Map<Id, Opportunity> oldMap){
    if (!(Trigger.isBefore && Trigger.isUpdate)) {
            return;
        }   
System.debug('-----SBG007OpportunityTrigger start');
        Map<Id, Id> accIds = new Map<Id, Id>();
                List<String> strlist = new List<String>();
                for (Opportunity newOpp : newList) {
                    strlist.add(newOpp.id);
                }

                for (Opportunity newOpp : newList) {
                     Opportunity oldOpp = oldMap.get(newOpp.Id);
                     if (newOpp.the_Upload_of_quotation_number__c != oldOpp.the_Upload_of_quotation_number__c 
                             && String.isblank(newOpp.the_Upload_of_quotation_number__c) == false){
                        SBG007TriggerHandler.SBG007_Ids.add(newOpp.Id);
                        BatchIF_Log__c iflog = new BatchIF_Log__c();
                        iflog.Type__c = 'SBG007';
                        iflog.Log__c  = 'callout start\n';
                        insert iflog;
                        iflog = [Select Id, Name from BatchIF_Log__c where Id = :iflog.Id];
                        SBG007TriggerHandler.callout(iflog.id,strlist,new Map<String,String>());
            }
        }
    } 



    /**
     * SBG007の送信処理s
     *
     * @param iflog_Id           ログテーブルのId
     * @param oppIds             送信対象商談(論理上1件のみです)
     * @param purposeOfAdviceMap 1:Delete 2:Add(Insert) 3:Change(Update)
     */
    @future (callout=true)
    public static void callout(String iflog_Id, List<String> oppIds, Map<String, String> purposeOfAdviceMap) {
        if (oppIds == null || oppIds.size() == 0) {
            return;
        }
        /*Sbg007Sync.HTTPS_Port stub = new Sbg007Sync.HTTPS_Port();
        stub.timeout_x = 100000; // timeout in milliseconds
        stub.endpoint_x = NFMUtil.SBG007_ENDPOINT;
        stub.inputHttpHeaders_x = new Map<String, String>();
        stub.inputHttpHeaders_x.put('Authorization', NFMUtil.Authorization);
        if (NFMUtil.CLIENT_CERT_NAME != null) {
            stub.clientCertName_x = NFMUtil.CLIENT_CERT_NAME;
        }*/

        // MessageGroupNumber の取得
        List<BatchIF_Log__c> iflogList = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog_Id];
        BatchIF_Log__c iflog = null;
        if (iflogList.size() > 0) {
            iflog = iflogList.get(0);
            iflog.ErrorLog__c = '';
        } else {
            // データ取れってないとは、rollbackされていることです
            return;
        }
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + oppIds.size() + '\n';

        // Monitoringの設定
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        //007修改Rest gwy start 2021-04-06
        //Sbg007Sync.GeDatas_element quotations = new Sbg007Sync.GeDatas_element();
        //quotations.Monitoring = new OlympusCoJpCommonMessage.Monitoring();
        GeDatas_element quotations = new GeDatas_element();
        quotations.Monitoring = new NFMUtil.Monitoring();
        //007修改Rest gwy end 2021-04-06
        quotations.Monitoring.Tag                  = 'MSGH';
        quotations.Monitoring.Sender               = '8402';
        quotations.Monitoring.Receiver             = '1330';
        quotations.Monitoring.MessageType          = 'SBG007';
        quotations.Monitoring.MessageGroupNumber   = iflog.Name;
        quotations.Monitoring.NumberOfRecord       = '' + oppIds.size();
        quotations.Monitoring.TransmissionDateTime = nowStr;
        quotations.Monitoring.Text = '';

        BatchIF_Log__c rowData = null;
        try {
            // 転送データを取得、参照先のデータがあるので、ここで検索必要です。
            List<Opportunity> oppList = [select Id, Name, CurrencyIsoCode,
                                                Owner.Name,AccountId__c,Account.ManagementCode_F__c,Dealer__r.DummyDealer__c,InquiryNumber__c,
                                                ProductSegment__c, TradeType__c,
                                                EndUser__c, Machine_Parts__c,
                                                SalesChannel__c, ExpectedDeliveryDate__c, DealerId__c,Dealer__r.ManagementCode_F__c,Dealer__r.ManagementCode_Ext__c,DealerSalesStaffName__c,
                                                ForeignTradeCompany__c, SpecialDeliveryAddress__c,
                                                SyncedQuoteId
                                           from Opportunity where Id IN :oppIds];
System.debug('11111 oppList='+oppList);
            
            //XHL-20190510-AddStart
            List<String> syncedQuoteIdList = new List<String>();
            //Map<String,String> appMap = new Map<String,String>();
            for (Opportunity opp : oppList) {
                syncedQuoteIdList.add(opp.SyncedQuoteId);
                system.debug('SyncedQuoteId__20190528__' + opp.SyncedQuoteId);
                //appMap.put(opp.Id,opp.SyncedQuoteId);
            }
            List<DecideQuoteProductSet__c> decideQuoteProductSetList = [
                                select Id,Name,DecideProductSet__c,DecideProductSetCount__c,
                                    DecideOpportunity__c,DecideProductSet__r.Code__c,
                                    DecideQuote__c,DecideProductSet__r.Name
                                from DecideQuoteProductSet__c
                                where DecideQuote__c In :syncedQuoteIdList
                                ];
            //Map<String,String> bppMap = new Map<String,String>();
            Map<String,String> dqpsNameAndCountMap = new Map<String,String>();
            String name ; String count;
            String value; String bppMapGetValue;

            for (DecideQuoteProductSet__c dqps :decideQuoteProductSetList) {
                name = dqps.DecideProductSet__r.Code__c;
                count = String.valueOf(dqps.DecideProductSetCount__c);
                value = name +','+ count;
                if (dqpsNameAndCountMap.containsKey(dqps.DecideQuote__c)) {

                    bppMapGetValue = dqpsNameAndCountMap.get(dqps.DecideQuote__c) +';'+ value ;
                    dqpsNameAndCountMap.put(dqps.DecideQuote__c, bppMapGetValue);
                } else {
                    dqpsNameAndCountMap.put(dqps.DecideQuote__c, value);
                }
                //bppMap.put(dqps.DecideQuote__c+','+,count+','+code )  
            }
            //XHL-20190510-AddEnd

            // Quotationのデータの設定
            //007修改Rest gwy start 2021-04-06
            //quotations.GeData = new List<Sbg007Sync.GeData_element>();
            quotations.GeData = new List<GeData_element>();
            //007修改Rest gwy end 2021-04-06
            for (Opportunity opp : oppList) { 
                // 商談商品情報を取得 
                List<OpportunityLineItem> oppLiList = 
                                        [select Id, Quantity, PricebookEntry.ProductCode, 
                                            OpportunityId,OLISingleProduct__c
                                         from OpportunityLineItem 
                                         where Opportunity.Id = :opp.Id 
                                         order by OLISingleProduct__c desc];

                system.debug('oppLiList_20190528_' +oppLiList);
                //007修改Rest gwy start 2021-04-06
                //Sbg007Sync.GeData_element quotation = new Sbg007Sync.GeData_element();
                GeData_element quotation = new GeData_element();
                //007修改Rest gwy end 2021-04-06
                if (opp.Dealer__r.DummyDealer__c == true){
                quotation.SalesAccountCode                   = opp.Account.ManagementCode_F__c;
                quotation.DealerCode          = opp.Account.ManagementCode_F__c;
                }
                else{
                quotation.SalesAccountCode                   = opp.Dealer__r.ManagementCode_F__c;
                quotation.DealerCode          = opp.Dealer__r.ManagementCode_Ext__c;
                }
                quotations.GeData.add(quotation);
                quotation.OpportunityCode                = opp.InquiryNumber__c;
//                quotation.SalesAccountCode                   = opp.Dealer__r.ManagementCode_F__c;
                quotation.ProductSegment              = opp.ProductSegment__c;
                quotation.TradeType              = opp.TradeType__c;
                quotation.MachineParts                   = opp.Machine_Parts__c;
                quotation.SalesChannel   = opp.Machine_Parts__c == 'Parts' ? '40' : opp.SalesChannel__c == 'dealer' ?  '41' : '42';
                quotation.ExpectedDeliveryDate          = NFMUtil.formatDate2Str(opp.ExpectedDeliveryDate__c);
//                quotation.DealerCode          = opp.Dealer__r.ManagementCode_Ext__c;
                quotation.DealerSalesStaffName         = opp.DealerSalesStaffName__c;
                quotation.ForeignTradeCompany                   = opp.ForeignTradeCompany__c;
                quotation.SpecialDeliveryAddress                   = opp.SpecialDeliveryAddress__c;
                
                //007修改Rest gwy start 2021-04-06
                quotation.GeDataDetails = new List<GeDataDetails_element>();
                //007修改Rest gwy end 2021-04-06
                Integer m = 0 ;
                for (Integer i = 0; i < oppLiList.size(); i++) {
                    //XHL-20190510-AddStart
                    if (!oppLiList.get(i).OLISingleProduct__c) {
                        continue;
                    } 
                    m++;
                    //XHL-20190510-AddEnd
                    //007修改Rest gwy start 2021-04-06
                    GeDataDetails_element detail = new GeDataDetails_element();
                    //007修改Rest gwy end 2021-04-06
                    quotation.GeDataDetails.add(detail);
                    detail.DetailLine                  = (i + 1) * 10;
                    detail.ItemCode                    = oppLiList.get(i).PricebookEntry.ProductCode;
                    detail.ItemQuantity                = Integer.valueOf(oppLiList.get(i).Quantity);
                }

                //XHL-20190510-AddStart
                if (dqpsNameAndCountMap.containsKey(opp.SyncedQuoteId)) {
                    value = dqpsNameAndCountMap.get(opp.SyncedQuoteId);
                    List<String> nameCountList = new List<String>();
                    for (String str: value.split(';')){
                        nameCountList.add(str);
                    }
                    if (nameCountList.size() > 0 ){
                        for (String  namCount :nameCountList) {
                            //007修改Rest gwy start 2021-04-06
                            //Sbg007Sync.GeDataDetails_element detail = new Sbg007Sync.GeDataDetails_element();
                            GeDataDetails_element detail = new GeDataDetails_element();
                            //007修改Rest gwy end 2021-04-06
                            quotation.GeDataDetails.add(detail);
                            detail.DetailLine                  = (m + 1) * 10;
                            detail.ItemCode                    = namCount.split(',')[0];
                            detail.ItemQuantity                = Integer.valueOf(namCount.split(',')[1]);
                            m++;
                        }
                    }

                }
                //XHL-20190510-AddEnd

                logstr += quotation.OpportunityCode + '\n';

            }

            if (quotations.GeData.size() > 0) {
                //Sbg007Sync.Quotations_element[] pQuotations = new Sbg007Sync.Quotations_element[] { quotations };
                logstr += '\ncallout count=' + quotations.GeData.size();
                //OlympusCoJpCommonMessage.LOG_element[] logs = stub.SBG007_Sync_BC2GPI(pQuotations);
                // 原則非同期ですので、logsを確認する必要がないでしょう。
                NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
                Monitoring.Tag                  = quotations.Monitoring.Tag;
                Monitoring.Sender               = quotations.Monitoring.Sender;
                Monitoring.Receiver             = quotations.Monitoring.Receiver;
                Monitoring.MessageType          = quotations.Monitoring.MessageType;
                Monitoring.MessageGroupNumber   = quotations.Monitoring.MessageGroupNumber;
                Monitoring.NumberOfRecord       = quotations.Monitoring.NumberOfRecord;
                Monitoring.TransmissionDateTime = quotations.Monitoring.TransmissionDateTime;
                Monitoring.Text = '';
                //007修改Rest gwy start 2021-04-07
                SBG007 sBG007 = new SBG007();
                sBG007.GeDatas =  quotations;
                rowData = NFMUtil.makeRowData(Monitoring, 'SBG007', sBG007);
                //007修改Rest gwy end 2021-04-07
                execute(rowData, iflog);
            }
            Set<String> inquiryNoList = new Set<String>();

            Map<String, Opportunity> oppUpsertMap = new Map<String, Opportunity>();
            logstr += '\nend';
        } catch(Exception ex) {
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'SBG007_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'SBG007_' + iflog.Name + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
        }
        if (rowData != null) {
            insert rowData;
        }

        System.debug(Logginglevel.DEBUG, 'SBG007_' + iflog.Name + ' end');
        iflog.Log__c = logstr;
        update iflog;
    }

    public static void execute(BatchIF_Log__c rowData, BatchIF_Log__c iflog) {
        //gaozw
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        SBG007 sBG007 = (SBG007) JSON.deserialize(rowDataStr, SBG007.class);

        //007修改Rest gwy start 2021-04-07
        String logstr = sBG007.GeDatas.Monitoring.MessageGroupNumber + ' start\n';
        //007修改Rest gwy end 2021-04-07
        Boolean needUpdateIflog = false;
        if  (iflog == null) {
            needUpdateIflog = true;
            iflog = new BatchIF_Log__c();
            iflog.Type__c = 'SBG007';
            //007修改Rest gwy start 2021-04-07
            iflog.MessageGroupNumber__c = sBG007.GeDatas.Monitoring.MessageGroupNumber;
            //007修改Rest gwy end 2021-04-07
            iflog.Log__c = logstr;
            iflog.ErrorLog__c = '';
            insert iflog;
            iflog = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog.Id];
        } else {
            logstr = iflog.Log__c;
        }
        try{
            //gaozw
            /*Sbg007Sync.HTTPS_Port stub = new Sbg007Sync.HTTPS_Port();
            stub.timeout_x = 100000; // timeout in milliseconds
            stub.endpoint_x = NFMUtil.SBG007_ENDPOINT;
            stub.inputHttpHeaders_x = new Map<String, String>();
            stub.inputHttpHeaders_x.put('Authorization', NFMUtil.Authorization);
            if (NFMUtil.CLIENT_CERT_NAME != null) {
                stub.clientCertName_x = NFMUtil.CLIENT_CERT_NAME;
            }*/
            //007修改Rest gwy start 2021-04-12
            status = NFMUtil.sendToSapRet(rowDataStr, NFMUtil.SBG007_ENDPOINT); 
            if (status == 'OK') {
                logstr += '\n' + status;
                rowData.retry_cnt__c = 0;
            } else {
                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 = 'status:' + status +
                                          '\n错误次数已经超过自动送信设定的最大次数，请手动送信';
                }
            }
            //007修改Rest gwy end 2021-04-12
            //Sbg007Sync.GeDatas_element[] pQuotations = new Sbg007Sync.GeDatas_element[] { quotations };
            //OlympusCoJpCommonMessage.LOG_element[] logs = stub.SBG007_Sync_BC2GPI(pQuotations);
            rowData.retry_cnt__c=0;
        }catch(Exception ex) {
            // TODO IOException
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'SBG007_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'SBG007_' + iflog.Name + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';

            //---xiongyl---add
            if (rowData.retry_cnt__c == null) rowData.retry_cnt__c = 0;
            if (rowData.retry_cnt__c < batch_retry_max_cnt){
                rowData.retry_cnt__c++;
            }
            if (rowData.retry_cnt__c >= batch_retry_max_cnt){
                rowData.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowData.ErrorLog__c+'错误次数已经超过自动送信设定的最大次数，请手动送信';
            }
        }
        iflog.Log__c = logstr;
        if (needUpdateIflog) {
            update iflog;
            update rowData;
        }
    }
}