public with sharing class NFM207Controller {

    public static boolean isRunning = false;
    //通过NFM207.trriger进行触发
    public class GeDatas{
        public NFMUtil.Monitoring Monitoring;
        public NFM207Controller.GeData[] GeData;
    }

    public class GeData{
        public String AssistantNo;      //QIS助理员工编号
        public String QISCode;          //QIS编号
        public NFM207Controller.GeDataDetails[] Products;
    }

    public class GeDataDetails{
        public String ProductCode;      //产品编码
        public String ProductName;      //产品名称
        public String SerialNumber;     //保有设备(机身号(设备))，耗材(批号(耗材))
        public String ManagementNumber; //管理编码 注:只有保有设备有
        public String ContractNumber;   // 订单编码
        public String CreateDate ;      // 生产日期
        public String EndDate ;         // 有效期
    }

    @future (callout=true)
    public static void callout(String iflog_Id, List<String> qisIds){
        if (qisIds == null || qisIds.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=' + qisIds.size() + '\n';


        GeDatas gds = new GeDatas();
        NFMUtil.Monitoring me = new NFMUtil.Monitoring();
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmm');

        me.Tag                  = 'MSGH';
        me.Sender               = 'SFDC';
        me.Receiver             = 'SPO';
        me.MessageType          = 'NFM207';
        me.MessageGroupNumber   = iflog.Name;
        me.NumberOfRecord       = '' + qisIds.size();
        me.TransmissionDateTime = nowStr;
        me.Text = '';
        gds.Monitoring = me;
        BatchIF_Log__c rowData = null;

        try {

            List<QIS_Report__c> qisList = [select   Id,
                                                    Name,
                                                    Nonyushohin__c,
                                                    Consumable__c,
                                                    Contract_number__c,
                                                    QIS_product_name__c,
                                                    Lot_or_serial__c,
                                                    nonyushohin__r.Product2.ProductCode,
                                                    nonyushohin__r.TracingCode__c,
                                                    consumable__r.ProductCode,
                                                    Salesdepartment__c,
                                                    BusinessAssistantNo__r.Employee_No__c,
                                                    nonyushohin__r.ProductionDate__c,
                                                    nonyushohin__r.Guaranteen_end__c
                                             from   QIS_Report__c
                                            where   Id In :qisIds
                                            ];

            gds.GeData = new List<GeData>();
            GeData gd = new GeData();
            gd.Products = new List<GeDataDetails>();

            for (QIS_Report__c qis: qisList) {
                logstr += qis.Name + '\n';
                gds.GeData.add(gd);
                gd.QISCode = qis.Name;

                gd.AssistantNo = qis.BusinessAssistantNo__r.Employee_No__c;

                // 保有设备/耗材层级
                GeDataDetails  gdds = new GeDataDetails();
                gdds.ContractNumber = qis.Contract_number__c; // 订单编号
                gdds.ProductName = qis.QIS_product_name__c;   // QIS设备名
                //gdds.SerialNumber = qis.Lot_or_serial__c;     // 机身号/批号
                if (qis.Lot_or_serial__c.indexOf('(') >= 0 ) {
                    gdds.SerialNumber = qis.Lot_or_serial__c.SubString(0, qis.Lot_or_serial__c.indexOf('('));     // 机身号/批号
                } else {
                    gdds.SerialNumber = qis.Lot_or_serial__c;     // 机身号/批号
                }
                if (!String.isBlank(qis.nonyushohin__c)) {
                    // 保有设备
                    gdds.ProductCode = qis.nonyushohin__r.Product2.ProductCode;
                    gdds.ManagementNumber = qis.nonyushohin__r.TracingCode__c;
                    gdds.CreateDate = String.valueOf(qis.nonyushohin__r.ProductionDate__c);
                    gdds.EndDate = String.valueOf(qis.nonyushohin__r.Guaranteen_end__c);

                } else if (!String.isBlank(qis.consumable__c)) {
                    // 耗材
                    gdds.ProductCode = qis.consumable__r.ProductCode;
                    gdds.ManagementNumber = null;
                }

                gd.Products.add(gdds);

            }
            if (gds.GeData.size() > 0) {
                //logstr += '\ncallout count=' + gds.GeData.size();
                // 原則非同期ですので、logsを確認する必要がないでしょう。
                NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
                Monitoring.Tag                  = gds.Monitoring.Tag;
                Monitoring.Sender               = gds.Monitoring.Sender;
                Monitoring.Receiver             = gds.Monitoring.Receiver;
                Monitoring.MessageType          = gds.Monitoring.MessageType;
                Monitoring.MessageGroupNumber   = gds.Monitoring.MessageGroupNumber;
                Monitoring.NumberOfRecord       = gds.Monitoring.NumberOfRecord;
                Monitoring.TransmissionDateTime = gds.Monitoring.TransmissionDateTime;
                Monitoring.Text = '';


                rowData = NFMUtil.makeRowData(Monitoring, 'NFM207', gds);
                execute(rowData, iflog);

            }
            logstr += '\nend';
            rowData.retry_cnt__c=0;
        } catch (Exception ex) {
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, 'NFM207_' + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, 'NFM207_' + 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, 'NFM001_' + iflog.Name + ' end');
        iflog.Log__c = logstr;
        update iflog;
    }
    public static void execute(BatchIF_Log__c rowData, BatchIF_Log__c iflog) {
        //xinhonglu
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);
        String rowDataStr = NFMUtil.getRowDataStr(rowData);

        GeDatas gds = (GeDatas) JSON.deserialize(rowDataStr, GeDatas.class);

        String logstr = gds.Monitoring.MessageGroupNumber + ' start\n';
        Boolean needUpdateIflog = false;
        if  (iflog == null) {
            needUpdateIflog = true;
            iflog = new BatchIF_Log__c();
            iflog.Type__c = 'NFM207';
            iflog.MessageGroupNumber__c = gds.Monitoring.MessageGroupNumber;
            iflog.Log__c = logstr;
            iflog.ErrorLog__c = '';

            } else {
                logstr = iflog.Log__c;
            }

            try {

                NFMUtil.sendToSpo(rowDataStr, NFMUtil.NFM207_ENDPOINT);

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


            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+'错误次数已经超过自动送信设定的最大次数，请手动送信';
            }
        }


        iflog.Log__c = logstr;
        if (needUpdateIflog) {
            insert iflog;
            update rowData;
        }
    }
}