// RowDataを残すため、@future execute にします
global class NFM002WebService {
    // Integer batchsize = 200;  考量する必要がないと思います。
    global class Agent {
        webservice NFMUtil.Monitoring Monitoring;
        webservice NFM002WebService.CustomerGeneralData[] CustomerGeneralData;
    }
    global class CustomerGeneralData {
        webservice String AgentCode;
        webservice String AgentName;
        webservice String Telephone;
        webservice String Fax;
        webservice String PostalCode;
        webservice String Address;
        webservice String RegionCode;                      // 受信しない
        webservice String VATRegistrationNumber;
        webservice String VATRegistrationNOvalidTo;
        webservice String MedicalProductionSalesLicenseNO;
        webservice String MedicalProductionSalesLicenseNOvalidTo;
        webservice String BusinessLicenseNO;
        webservice String BusinessLicenseNOvalidTo;
        webservice String ValidFrom;
        webservice String ValidTo;
        webservice String PurposeOfAdvice;
        webservice String AgentCategory;
    }

    // 非同期を見せかけ、常にreturn void
    webservice static void NFM002(NFM002WebService.Agent Agent) {
        if (Agent == null) {
            return;
        }
        NFMUtil.Monitoring Monitoring = Agent.Monitoring;
        if (Monitoring == null) {
            return;
        }

        BatchIF_Log__c rowData = NFMUtil.saveRowData(Monitoring, 'NFM002', Agent.CustomerGeneralData);
        if (String.isBlank(rowData.Log__c) == false) executefuture(rowData.Id);
    }

    @future
    global static void executefuture(String rowData_Id) {
        execute(rowData_Id);
    }
    global static void execute(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 Id = :rowData_Id];
        String logstr = rowData.MessageGroupNumber__c + ' start\n';
        BatchIF_Log__c iflog = new BatchIF_Log__c();
        iflog.Type__c = 'NFM002';
        iflog.MessageGroupNumber__c = rowData.MessageGroupNumber__c;
        iflog.Log__c = logstr;
        iflog.ErrorLog__c = '';
        insert iflog;

        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        List<CustomerGeneralData> customerGeneralDataList = (List<CustomerGeneralData>) JSON.deserialize(rowDataStr, List<CustomerGeneralData>.class);
        if (customerGeneralDataList == null || customerGeneralDataList.size() == 0) {
            return;
        }

        List<RecordType> rects = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = '販売店'];
        if (rects.size() == 0) {
            return;
        }

        // BatchIF転送表 から、コード変換のMapを作成
        Map<String, String> transferMap = new Map<String, String>();
        List<BatchIF_Transfer__c> transferList = [select Table__c,
                                                         Column__c,
                                                         External_value__c,
                                                         Internal_value__c
                                                    from BatchIF_Transfer__c
                                                   where Dropped_Flag__c = false
                                                     and Table__c = 'Account'];
        for (BatchIF_Transfer__c t : transferList) {
            transferMap.put(t.Column__c + t.External_value__c, t.Internal_value__c);
        }

        Savepoint sp = Database.setSavepoint();
        try {
            // 更新対応配列をセット
            List<Account> accList = new List<Account>();
            List<String> agentCodeList = new List<String>();
            Map<String, Account> accUpdateMap = new Map<String, Account>();
            List<Account> updateAccList;
            Map<String,Account> updateAccMap = new Map<String,Account>();
            for (NFM002WebService.CustomerGeneralData CustomerGeneralData : customerGeneralDataList) {
                if (CustomerGeneralData.AgentCode == null || CustomerGeneralData.AgentCode == '') {
                    continue;
                }
                agentCodeList.add(CustomerGeneralData.AgentCode);
            }

            updateAccList = [select Id , Name ,AgentCode_Ext__c from Account where AgentCode_Ext__c In :agentCodeList];
            
            for(Account acc: updateAccList){
                updateAccMap.put(acc.AgentCode_Ext__c, acc);
            }
            
            for (NFM002WebService.CustomerGeneralData CustomerGeneralData : customerGeneralDataList) {
                if (CustomerGeneralData.AgentCode == null || CustomerGeneralData.AgentCode == '') {
                    // 必須項目がない場合、処理と飛ばす
                    iflog.ErrorLog__c += 'AgentCode is required\n';
                    continue;
                }

                // 項目転送のセット
                Account acc = new Account();
                acc.AgentCode_Ext__c = CustomerGeneralData.AgentCode;
                if (updateAccMap.get(acc.AgentCode_Ext__c) == null) {
                    accList.add(acc);
                    updateAccMap.put(acc.AgentCode_Ext__c, acc);
                    logstr += CustomerGeneralData.AgentCode + ' ';
                } else {
                    acc = updateAccMap.get(acc.AgentCode_Ext__c);
                    if(updateAccMap.get(acc.AgentCode_Ext__c).Name != CustomerGeneralData.AgentName){
//*************************Update 20180903 CHAN-B44AZ6 xinhonglu Start***************************//
                        acc.Sap2sfdcDealers_ModifycationLogo__c = '1';
//*************************Update 20180903 CHAN-B44AZ6 xinhonglu End***************************//  
                    }
                    accList.add(acc);
                }
                
                acc.RecordTypeId = rects[0].Id;
                if (CustomerGeneralData.PurposeOfAdvice == '1') {
                    // deleteの場合、AgentName先頭に、「删除:」をつける
                    acc.Delete_Flag__c                   = True;
                    //*************************Update 20180903 CHAN-B44AZ6 xinhonglu Start***************************//
                    acc.Name                             = '删除:' + CustomerGeneralData.AgentName;
                    //*************************Update 20180903 CHAN-B44AZ6 xinhonglu End***************************// 
                    acc.Sap2sfdcDealers_ModifycationLogo__c = '1';
                } else {
                    acc.Delete_Flag__c                   = False;
                    acc.Name                             = CustomerGeneralData.AgentName;

                }
                acc.Phone                                = CustomerGeneralData.Telephone;
                acc.Fax                                  = CustomerGeneralData.Fax;
                acc.Postal_Code__c                       = CustomerGeneralData.PostalCode;
                acc.Address_Together__c                  = CustomerGeneralData.Address;
                acc.Tax_Practice_No__c                   = CustomerGeneralData.VATRegistrationNumber;
                acc.Tax_Practice_Expiration_Date__c      = NFMUtil.parseStr2Date(CustomerGeneralData.VATRegistrationNOvalidTo);
//*************************Update 20160802 HHOA-ACEE9N 趙徳芳 Start*************************//
//*************************Update 20160817 HHOA-ACEE9N_SecondMatch 趙徳芳 Start*************************//
                //acc.Business_Authorization_No__c       = CustomerGeneralData.MedicalProductionSalesLicenseNO;
                acc.Medical_Equipment_Num__c             = CustomerGeneralData.MedicalProductionSalesLicenseNO;
                acc.Medical_Equipment_Expiration_Date__c = NFMUtil.parseStr2Date(CustomerGeneralData.MedicalProductionSalesLicenseNOvalidTo);
                //acc.Medical_Equipment_Num__c           = CustomerGeneralData.BusinessLicenseNO;
                acc.Business_Authorization_No__c         = CustomerGeneralData.BusinessLicenseNO;
                acc.Business_Paper_Expiration_Date__c    = NFMUtil.parseStr2Date(CustomerGeneralData.BusinessLicenseNOvalidTo);
//*************************Update 20160817 HHOA-ACEE9N_SecondMatch 趙徳芳 End***************************//
//*************************Update 20160802 HHOA-ACEE9N 趙徳芳 End***************************//
                acc.Registration_Day__c                  = NFMUtil.parseStr2Date(CustomerGeneralData.ValidFrom, false);
                acc.Ban_On_Use_Date__c                   = NFMUtil.parseStr2Date(CustomerGeneralData.ValidTo);
                acc.Sales_Shop_Class__c                  = NFMUtil.getMapValue(transferMap, 'Sales_Shop_Class__c', CustomerGeneralData.AgentCategory, iflog);
            }
            System.debug('accList' + accList);
            if (accList.size() > 0) {
                //*************************Update 20180903 CHAN-B44AZ6 xinhonglu Start***************************// 
                StaticParameter.EscapeNFM001AgencyContractTrigger2 = true;
                //*************************Update 20180903 CHAN-B44AZ6 xinhonglu End***************************//
                upsert accList AgentCode_Ext__c;
            }
            logstr += '\nend';
            rowData.retry_cnt__c=0;
        } catch(Exception ex) {
            // エラーが発生した場合
            Database.rollback(sp);
            System.debug(Logginglevel.ERROR, 'NFM002_' + rowData.MessageGroupNumber__c + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM002_' + 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;
    }
}