/**
 * NFM201.trigger触发
 */
public without sharing class NFM201Controller {
	public static boolean isRunning = false;
    public static String debug_msg = '';
    public static String status;

    public class Endusers_element {
        public NFMUtil.Monitoring Monitoring;
        public Gedata[] GeData;
    }

    public class GeData {
        public String ManageCode;
        public String HospitalName;
        public String HospitalAlias;
        public String AttributeType;
        public String Grade;
        public String SpecialityType;
        public String GovermentKeyCustomer;
        public String State;
        public String City;
        public String Town;
        public String Telehone;
        public String Fax;
        public String ZIPCode;
        public String Address;
        public String Category;
        public String TermDate;
        public String PurposeOfAdvice;
        public String SectionCategory;
        public String SectionName;
        public String SectionCode;
        public Boolean NeedQuolified;
    }

	/**
     * NFM201の送信処理
     *
     * @param iflog_Id           ログテーブルのId
     * @param accIds             送信対象取引先
     * @param purposeOfAdviceMap 1:Delete 2:Add(Insert) 3:Change(Update)
     * @param needSendRectMap    送信対象のレコードタイプのmap
     */
    @future (callout=true)
    //NFM624触发001和201接口 20221102 LY start
    public static void callout(String iflog_Id, List<String> accIds, Map<String, String> purposeOfAdviceMap, Map<String, String> needSendRectMap, Map<String, String> needQuolifiedMap) {
        calloutNotFuture(iflog_Id,accIds,purposeOfAdviceMap,needSendRectMap,needQuolifiedMap);
    }
    //NFM624触发001和201接口 20221102 LY end
    public static void calloutNotFuture(String iflog_Id, List<String> accIds, Map<String, String> purposeOfAdviceMap, Map<String, String> needSendRectMap, Map<String, String> needQuolifiedMap) {
        if (accIds == null || accIds.size() == 0) {
            return;
        }

        // 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=' + accIds.size() + '\n';

        // Monitoringの設定
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');
        Endusers_element endusers = new Endusers_element();
        endusers.Monitoring = new NFMUtil.Monitoring();
        endusers.Monitoring.Tag                  = 'MSGH';
        endusers.Monitoring.Sender               = 'SFDC';
        endusers.Monitoring.Receiver             = 'SPO';
        endusers.Monitoring.MessageType          = 'NFM201';
        endusers.Monitoring.MessageGroupNumber   = iflog.Name;
        endusers.Monitoring.NumberOfRecord       = '' + accIds.size();
        endusers.Monitoring.TransmissionDateTime = nowStr;
        endusers.Monitoring.Text = '';

        BatchIF_Log__c rowData = null;
        // 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.Internal_value__c, t.External_value__c);
        }

        try {
            // 転送データを取得、参照先のデータがあるので、ここで検索必要です。
            List<Account> accList = [select Id, RecordTypeId,
                                            Management_Code__c,
                                            Name,
                                            site,
                                            Alias_Name2__c,
                                            Attribute_Type__c,
                                            Grade__c,
                                            Speciality_Type__c,
                                            Goverment_key_customer__c,
                                            State_Text__c,
                                            City_Master__r.name,
                                            //City_Master__r.Level2_Sys_No__c,
                                            Town__c,
                                            Department_Name__c,
                                            Phone,
                                            Fax,
                                            Postal_Code__c,
                                            Street__c,
                                            OCM_Category__c,
                                            Ban_On_Use_Date__c,
                                            //If_Need_Quolified__c, 
                                            Department_Class__r.Department_Class_Label__c,
                                            Hospital__r.Name,
                                            Hospital__r.Management_Code__c,
                                            Hospital__r.Alias_Name2__c,
                                            Hospital__r.site,
                                            Hospital__r.Attribute_Type__c,
                                            Hospital__r.Grade__c,
                                            Hospital__r.Speciality_Type__c,
                                            Hospital__r.Goverment_key_customer__c,
                                            Hospital__r.State_Text__c,
                                            //Hospital__r.City_Master__r.Level2_Sys_No__c,
                                            Hospital__r.City_Master__r.name,
                                            Hospital__r.Town__c,
                                            Hospital__r.Postal_Code__c,
                                            Hospital__r.Street__c,
                                            Hospital__r.OCM_Category__c,
                                            //Hospital__r.If_Need_Quolified__c, 
                                            Hospital__r.Ban_On_Use_Date__c
                                       from Account where Id IN :accIds All ROWS];
            System.debug(Logginglevel.DEBUG, 'NFM201_ accList.size()=' + accList.size());

            // Enduserのデータの設定
            endusers.GeData = new List<GeData>();
            for (Account acc : accList) {
                GeData endUser = new GeData();
                endusers.GeData.add(endUser);
                if (needSendRectMap.get(acc.RecordTypeId) == '病院') {
                    endUser.ManageCode            = acc.Management_Code__c;
                    endUser.HospitalName          = acc.Name;
                    endUser.HospitalAlias         = ((acc.site == null) ? '' : acc.site + ';')  
                                                    + ((acc.Alias_Name2__c == null) ? '' : acc.Alias_Name2__c + ';');
                    endUser.AttributeType         = acc.Attribute_Type__c;
                    endUser.Grade                 = acc.Grade__c;
                    endUser.SpecialityType        = acc.Speciality_Type__c;
                    endUser.GovermentKeyCustomer  = acc.Goverment_key_customer__c;
                    endUser.State                 = acc.State_Text__c;
                    //endUser.City                  = acc.City_Master__r.Level2_Sys_No__c;
                    endUser.City                  = acc.City_Master__r.name;
                    endUser.Town                  = acc.Town__c;
                    endUser.ZIPCode               = acc.Postal_Code__c;
                    endUser.Address               = acc.Street__c;
                    endUser.Category              = NFMUtil.getMapValue(transferMap, 'OCM_Category__c', acc.OCM_Category__c, iflog);
                    endUser.TermDate              = NFMUtil.formatDate2StrSpo(acc.Ban_On_Use_Date__c);
                    endUser.PurposeOfAdvice       = purposeOfAdviceMap.get(acc.Id);
                    endUser.SectionCategory       = '';
                    endUser.SectionName           = acc.Name;
                    endUser.SectionCode           = acc.Management_Code__c;
                    //endUser.NeedQuolified         = acc.If_Need_Quolified__c;
                    if (needQuolifiedMap.containsKey(acc.Id)) {
                        endUser.NeedQuolified         = true;
                    } else {
                        endUser.NeedQuolified         = false;
                    }
                } else {
                    endUser.ManageCode            = acc.Hospital__r.Management_Code__c;
                    endUser.HospitalName          = acc.Hospital__r.Name;
                    //endUser.HospitalAlias         = acc.Hospital__r.site + ';' + acc.Hospital__r.Alias_Name2__c;
                    endUser.HospitalAlias         = ((acc.Hospital__r.site == null) ? '' : acc.Hospital__r.site + ';')  
                                                    + ((acc.Hospital__r.Alias_Name2__c == null) ? '' : acc.Hospital__r.Alias_Name2__c + ';');
                    endUser.AttributeType         = acc.Hospital__r.Attribute_Type__c;
                    endUser.Grade                 = acc.Hospital__r.Grade__c;
                    endUser.SpecialityType        = acc.Hospital__r.Speciality_Type__c;
                    endUser.GovermentKeyCustomer  = acc.Hospital__r.Goverment_key_customer__c;
                    endUser.State                 = acc.Hospital__r.State_Text__c;
                    //endUser.City                  = acc.Hospital__r.City_Master__r.Level2_Sys_No__c;
                    endUser.City                  = acc.Hospital__r.City_Master__r.Name;
                    endUser.Town                  = acc.Hospital__r.Town__c;
                    endUser.ZIPCode               = acc.Hospital__r.Postal_Code__c;
                    endUser.Address               = acc.Hospital__r.Street__c;
                    endUser.Category              = NFMUtil.getMapValue(transferMap, 'OCM_Category__c', acc.Hospital__r.OCM_Category__c, iflog);
                    endUser.TermDate              = NFMUtil.formatDate2StrSpo(acc.Hospital__r.Ban_On_Use_Date__c);
                    endUser.PurposeOfAdvice       = purposeOfAdviceMap.get(acc.Id);
                    endUser.SectionCategory       = NFMUtil.getMapValue(transferMap, 'Department_Class_Label__c', acc.Department_Class__r.Department_Class_Label__c, iflog);
                    //endUser.SectionName           = acc.Department_Name__c;
                    //NFM624触发001和201接口 LY 20221109 start
                    if(UserInfo.getUserId().equals(System.Label.interfaceUserID)){
                        endUser.SectionName           = acc.Hospital__r.Name+' '+acc.Department_Class__r.Department_Class_Label__c+' '+acc.Department_Name__c;
                    }else{
                        endUser.SectionName           = acc.name;
                    }
                    //NFM624触发001和201接口 LY 20221109 end
                    endUser.SectionCode           = acc.Management_Code__c;
                    //endUser.NeedQuolified         = acc.Hospital__r.If_Need_Quolified__c;
                    endUser.NeedQuolified         = false;
                }
                endUser.Telehone                  = acc.Phone;
                endUser.Fax                       = acc.Fax;

                logstr += endUser.SectionCode + '(' + endUser.PurposeOfAdvice + ')' + ' ';
            }


            if (endusers.GeData.size() > 0) {

                NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
                Monitoring.Tag                  = endusers.Monitoring.Tag;
                Monitoring.Sender               = endusers.Monitoring.Sender;
                Monitoring.Receiver             = endusers.Monitoring.Receiver;
                Monitoring.MessageType          = endusers.Monitoring.MessageType;
                Monitoring.MessageGroupNumber   = endusers.Monitoring.MessageGroupNumber;
                Monitoring.NumberOfRecord       = endusers.Monitoring.NumberOfRecord;
                Monitoring.TransmissionDateTime = endusers.Monitoring.TransmissionDateTime;
                Monitoring.Text = '';
                rowData = NFMUtil.makeRowData(Monitoring, 'NFM201', endusers);
                execute(rowData, iflog);

            }
            logstr +='\nStatus:' + status;
            logstr += '\nend';

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

        iflog.Log__c = logstr;
        update iflog;
    }

    public static void execute(BatchIF_Log__c rowData, BatchIF_Log__c iflog) {

        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        String rowDataStr = NFMUtil.getRowDataStr(rowData);
        Endusers_element endusers = (Endusers_element) JSON.deserialize(rowDataStr, Endusers_element.class);

        String logstr = endusers.Monitoring.MessageGroupNumber + ' start\n';
        Boolean needUpdateIflog = false;
        if  (iflog == null) {
            needUpdateIflog = true;
            iflog = new BatchIF_Log__c();
            iflog.Type__c = 'NFM201';
            iflog.MessageGroupNumber__c = endusers.Monitoring.MessageGroupNumber;
            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 {
            //iflog = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog.Id];
            logstr = iflog.Log__c;
        }

        try{
            // 向SPO送信
           // NFMUtil.sendToSpo(rowDataStr, NFMUtil.NFM201_ENDPOINT);
           status = NFMUtil.sendToSpoRet(rowDataStr, NFMUtil.NFM201_ENDPOINT);
           if (status == 'OK') {
                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+'错误次数已经超过自动送信设定的最大次数，请手动送信';
                }
            }

        } catch (Exception ex) {
            // TODO IOException
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'NFM201_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM201_' + iflog.Name + ':' + ex.getStackTraceString());

            //NFM624触发001和201接口 20221102 LY start
            // Callout from triggers are currently not supported.
            System.debug('NFM201jiekou'+ex.getMessage());
            if (!String.valueOf(ex.getMessage()).contains('Callout from triggers')) {

                logstr += ex.getMessage();
                iflog.ErrorLog__c += ex.getMessage() + '\n';
                iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
            }
            //NFM624触发001和201接口 20221102 LY end

            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+'错误次数已经超过自动送信设定的最大次数，请手动送信';
            }
        }
        logstr +='\nStatus:' + status;
        iflog.Log__c = logstr;

        if (needUpdateIflog) {
            upsert iflog;
            update rowData;
        }
    }
}