public without sharing class NFM614Controller {

    private static final String LOG_TYPE = 'NFM614';
    // private static final String API = '/admin/api/scd/save';
    private static final String API = '/admin/api/repair/save1111111';
    public class NFM614 {
    	public GeDatas GeDatas;
    }
    public class GeDatas {
    	// public applyRepairInfo[] applyRepairInfo;
    	// public problem[] problem;
        public NFMUtil.MonitoringToComPlat Monitoring;
    	public GeData[] GeData;
    }
    public class GeData {
    	public rentalApplyEquipmentSet[] Rental_Apply_Equipment_Set;
        public String rentalApplyNo; // 备品单编号
        public String repairNo; // 修理单号
        public String hospitalCode; // 医院编码
        public String hospitalName; // 医院名称
        public String strategicDepartmenCode; // 战略科室编码
        public String strategicDepartmenName; // 战略科室
        public String departmentCode; // 科室编码
        public String departmentName; // 科室
        public String region; // 大区
        public String province; // 省
        public String city; // 市
        public String rentalApplyStatus; // 备品状态
        public String rentalApplyEmpNo; // 申请人编号
        public String workPlace; // 申请人办事处
        public String queueStatus; // 排队状态
        public String demoPurpose1; // 使用目的1
        public String demoPurpose2; // 使用目的2
        public String productCategory; // 产品分类
        public String queueShippmentDate; // 排队备品预计出库时间
        public String newExpectedReturnDate; // 最新预定归还日
        public String expectedReturnDate; // 预定归还日
        public String receivedSignDay; // 用户装机日
        public String requestDemoDay; // 申请日期
        public String bollowDate; // 备品中心出库日
        public String loanerReceivedDay; // 现场签收日
        public String assetReturnDay; // 回寄日
        public String cancelDate; // 备品申请取消日
        public String cannelReason; // 取消理由
        public Decimal expectedBorrowingDays; // 希望借用天数
        public String selectStatus; // 希望借用天数
        public String approvalDate; // 批准日
    }
    public class rentalApplyEquipmentSet {
        public String equipmentName;
		public rentalApplyEquipmentSetDetail[] Rental_Apply_Equipment_Set_Detail; //明细
    }
    public class rentalApplyEquipmentSetDetail{
        public Decimal queueNo; // 排队编号
        public String assetModel; // 设备型号
        public String equipmentDetailName;
    }
    @future(callout = true)
    public static void callout(String iflog_Id, List < String > rentalApplyIdList) {
        List < BatchIF_Log__c > iflog = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = :iflog_Id];
        String sql = 'Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id = \'' + iflog_Id + '\'';
        // List < BatchIF_Log__c > iflog = DataBase.query(sql);
        System.debug(iflog + 'NFM614======');
        if (iflog == null || iflog.size() == 0) {
        	System.debug(iflog + 'NFM614======null');
            executefuture(null, rentalApplyIdList);
        } else {
        	System.debug(iflog + 'NFM614======null1');
            executefuture(iflog.get(0), rentalApplyIdList);
        }

    }

    public static void executefuture(BatchIF_Log__c iflog, List < String > rentalApplyIdList) {
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmmss');
        if (iflog != null) {
            iflog.ErrorLog__c = '';
        } else {
            iflog = new BatchIF_Log__c();
            iflog.Type__c = LOG_TYPE;
            iflog.ErrorLog__c = '';
            iflog.Log__c = 'callout start \n';
            iflog.MessageGroupNumber__c = nowStr;
        }
        NFMUtil.MonitoringToComPlat me = new NFMUtil.MonitoringToComPlat();
        me.Tag                  = 'MSGH';
        me.Sender               = 'SFDC';
        me.Receiver             = '智慧医疗/服务新系统';
        me.MessageType          = LOG_TYPE;
        me.MessageGroupNumber   = nowStr;
        if (String.isNotBlank(iflog.Name)) {
            me.MessageGroupNumber = iflog.Name;
        }
        me.TransmissionDateTime = nowStr;
        me.Text = '';
        String randomstr = NFMUtil.randomUUID(16);
        Long timestamp = DateTime.now().getTime();
        String timestampStr = String.valueOf(timestamp);
        String getToken = NFMUtil.getToken(randomstr, timestamp);
        me.API_RANDOM_STR = randomstr;
        me.API_TIME = timestampStr;
        me.API_TOKEN = getToken;
        BatchIF_Log__c rowData = null;
        List<Rental_Apply__c> raList = new List<Rental_Apply__c>();
        raList = [SELECT Id,
        					Name,
        					Status__c,
        					Repair__r.Name,
        					Hospital__r.Parent_Management_Code__c,
        					Hospital__r.Name,
        					Strategic_dept__r.AccountManageNumber__c,
                            Person_In_Charge__r.Employee_No__c,
        					Strategic_dept__r.Name,
        					Account__r.Management_Code__c,
        					Account__r.Name,
        					User_Salesdept__c,
        					Province__c,
        					HP_City__c,
        					RA_Status__c,
        					WorkPlace__c,
        					Queue_Status__c,
        					Demo_purpose1__c,
        					demo_purpose2__c,
        					Product_category__c,
        					QueueShippmentDate__c,
        					Return_dadeline_final__c,
        					Request_return_day__c,
                            HP_received_sign_day__c,
                            Request_demo_day__c,
                            Bollow_Date__c,
                            Loaner_received_day__c,
                            Asset_return_day2__c,
                            Cancel_date__c,
                            Cancel_Reason__c,
                            Select_Status__c,
                            Request_approval_time__c,
                            Hope_Lonaer_date_Num__c
        					FROM Rental_Apply__c WHERE Id IN :rentalApplyIdList];
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + raList.size() + '\n';
        try{
        	GeDatas geds = new GeDatas();
        	// geds.applyRepairInfo = new List<applyRepairInfo>();
        	// geds.problem = new List<problem>();
            List < Id > raIdList = new List < Id > ();
            // List < Id > raesIdList = new List < Id > ();
            if (raList.size() > 0) {
                
                for (Rental_Apply__c ra: raList) {
                    raIdList.add(ra.Id);
                }
                Map < id, List < rentalApplyEquipmentSet >> raesMap = getRaesMap(raIdList);
                // if (raIdList.size() > 0) {
                //     List<Rental_Apply_Equipment_Set__c> raesList = [SELECT Id,Name,Rental_Apply__c FROM Rental_Apply_Equipment_Set__c WHERE Rental_Apply__c IN :raIdList];
                //     if (raesList.size() > 0) {
                //         for (Rental_Apply_Equipment_Set__c raes : raesList) {
                //             raesIdList.add(raes.Id);
                //         }
                //         if (raesIdList.size() > 0) {
                //             List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [SELECT Id,Name,Fixture_Model_No__c,Queue_Number__c,Rental_Apply_Equipment_Set__c FROM Rental_Apply_Equipment_Set_Detail__c WHERE Rental_Apply_Equipment_Set__c IN :raesIdList];
                //         }
                //     }
                // }
                List<GeData> gedList = new List<GeData>();
                rentalApplyEquipmentSet raes = new rentalApplyEquipmentSet();
                rentalApplyEquipmentSetDetail raesd = new rentalApplyEquipmentSetDetail();
                for (Rental_Apply__c ra : raList) {
                    GeData ged = new GeData();
                    ged.rentalApplyNo = ra.Name; // 备品单编号
                    ged.repairNo = ra.Repair__r.Name; // 修理单号
                    ged.hospitalCode = ra.Hospital__r.Parent_Management_Code__c; // 医院编码
                    ged.hospitalName = ra.Hospital__r.Name; // 医院名称
                    ged.strategicDepartmenCode = ra.Strategic_dept__r.AccountManageNumber__c; // 战略科室编码
                    ged.strategicDepartmenName = ra.Strategic_dept__r.Name; // 战略科室
                    ged.departmentCode = ra.Account__r.Management_Code__c; // 科室编码
                    ged.departmentName = ra.Account__r.Name; // 科室
                    ged.region = ra.User_Salesdept__c; // 大区
                    ged.province = ra.Province__c; // 省
                    ged.city = ra.HP_City__c; // 市
                    ged.rentalApplyStatus = ra.RA_Status__c; // 备品状态
                    ged.rentalApplyEmpNo = ra.Person_In_Charge__r.Employee_No__c;
                    ged.workPlace = ra.WorkPlace__c; // 申请人办事处
                    ged.queueStatus = ra.Queue_Status__c; // 排队状态
                    ged.demoPurpose1 = ra.Demo_purpose1__c; // 使用目的1
                    ged.demoPurpose2 = ra.demo_purpose2__c; // 使用目的2
                    ged.productCategory = ra.Product_category__c; // 产品分类
                    ged.queueShippmentDate = ra.QueueShippmentDate__c == null ? '' : NFMUtil.formatDate2Str(ra.QueueShippmentDate__c) + '000000'; // 排队备品预计出库时间
                    ged.newExpectedReturnDate = ra.Return_dadeline_final__c == null ? '' : NFMUtil.formatDate2Str(ra.Return_dadeline_final__c) + '000000'; // 最新预定归还日
                    ged.expectedReturnDate = ra.Request_return_day__c == null ? '' : NFMUtil.formatDate2Str(ra.Request_return_day__c) + '000000'; // 预定归还日
                    ged.receivedSignDay = ra.HP_received_sign_day__c == null ? '' : NFMUtil.formatDate2Str(ra.HP_received_sign_day__c) + '000000'; // 用户装机日
                    ged.requestDemoDay = ra.Request_demo_day__c == null ? '' : NFMUtil.formatDate2Str(ra.Request_demo_day__c) + '000000'; // 申请日期
                    ged.bollowDate = ra.Bollow_Date__c == null ? '' : NFMUtil.formatDate2Str(ra.Bollow_Date__c) + '000000'; // 备品中心出库日
                    ged.loanerReceivedDay = ra.Loaner_received_day__c == null ? '' : NFMUtil.formatDate2Str(ra.Loaner_received_day__c) + '000000'; // 现场签收日
                    ged.assetReturnDay = ra.Asset_return_day2__c == null ? '' : NFMUtil.formatDate2Str(ra.Asset_return_day2__c) + '000000'; // 回寄日
                    ged.cancelDate = ra.Cancel_date__c == null ? '' : NFMUtil.formatDate2Str(ra.Cancel_date__c) + '000000'; // 备品申请取消日
                    ged.cannelReason = ra.Cancel_Reason__c; // 取消理由
                    ged.expectedBorrowingDays = ra.Hope_Lonaer_date_Num__c; // 希望借用天数
                    ged.Rental_Apply_Equipment_Set = raesMap.get(ra.Id);
                    ged.selectStatus = ra.Select_Status__c;
                    ged.approvalDate = ra.Request_approval_time__c == null ? '' : NFMUtil.formatDateTime2Str(ra.Request_approval_time__c);

                    // geds.applyRepairInfo.add(info);
                    // geds.problem.add(pro);
                    System.debug('zyhtest11=====12'+ged);
                    gedList.add(ged);
                    geds.GeData = gedList;
                    // geds.problem = pro;
                    System.debug('zyhtest11=====1'+ged);
                }
                System.debug(geds);
                System.debug('zyhtest====='+geds);
                System.debug('zyhtest11====='+geds.GeData);
                logstr+= 'end';
                // if (geds.applyRepairInfo.size() > 0 || geds.problem.size() > 0) {
                if (geds.GeData != null) {
                    geds.Monitoring = me;
                    NFMUtil.Monitoring Monitoring   = new NFMUtil.Monitoring();
                    Monitoring.Tag                  = geds.Monitoring.Tag;
                    Monitoring.Sender               = geds.Monitoring.Sender;
                    Monitoring.Receiver             = geds.Monitoring.Receiver;
                    Monitoring.MessageType          = geds.Monitoring.MessageType;
                    Monitoring.MessageGroupNumber   = geds.Monitoring.MessageGroupNumber;
                    Monitoring.NumberOfRecord       = geds.Monitoring.NumberOfRecord;
                    Monitoring.TransmissionDateTime = geds.Monitoring.TransmissionDateTime;
                    Monitoring.Text = '';
                    NFM614 NFM614 = new NFM614();
                    NFM614.GeDatas = geds;
                    rowData = NFMUtil.makeRowData(iflog, LOG_TYPE, NFM614);
                    execute(rowData,iflog);
                }
            } else {
                System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + '没有数据,直接退回');
                System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + '没有数据,直接退回');
                logstr += '没有数据,直接退回';
                iflog.ErrorLog__c += '没有数据,直接退回' + '\n';
                iflog.ErrorLog__c += '没有数据,直接退回' + '\n';
                iflog.Log__c = iflog.Log__c + logstr;
                upsert iflog;
            }
        } catch (Exception e) {
            // 发生错误时
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + e.getMessage());
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + e.getStackTraceString());
            logstr += e.getMessage();
            iflog.ErrorLog__c += e.getMessage() + '\n';
            iflog.ErrorLog__c += e.getStackTraceString() + '\n';
            iflog.Log__c = iflog.Log__c + logstr;
            upsert iflog;
        }
    }

    /**
     * 接口发送失败 根据BatchLogId进行手动发送
     * @Author   XHL
     * @DateTime 2021-07-22
     * @param    rowDataId  [BatchLogId]
     */
    public static void ManualExecute(String rowDataId) {
        List < BatchIF_Log__c > row = [select id, name, MessageGroupNumber__c, retry_cnt__c,
            RowDataFlg__c, ErrorLog__c, Type__c,
            Log__c, Log2__c, Log3__c, Log4__c, Log5__c, Log6__c,
            Log7__c, Log8__c, Log9__c, Log10__c, Log11__c, Log12__c
            from BatchIF_Log__c
            where id =: rowDataId
        ];
        if (row.size() > 0) execute(row[0], null);
    }
    /**
     * 逻辑正常执行发送
     * @Author   XHL
     * @DateTime 2021-07-22
     * @param    rowDataSFDC [BatchLogId]
     * @param    iflog       [执行情况记录]
     */
    public static void execute(BatchIF_Log__c rowDataSFDC, BatchIF_Log__c iflog) {
        Integer batch_retry_max_cnt = Integer.valueOf(System.Label.batch_retry_max_cnt);

        String logstr = rowDataSFDC.Name + ' start\n';
        if (iflog == null) {
            iflog = new BatchIF_Log__c();
            iflog.Type__c = LOG_TYPE;
            iflog.MessageGroupNumber__c = rowDataSFDC.MessageGroupNumber__c;
            iflog.Log__c = logstr;
            iflog.ErrorLog__c = '';

        } else {
            iflog.Type__c = LOG_TYPE;
            iflog.MessageGroupNumber__c = rowDataSFDC.MessageGroupNumber__c;
            logstr = iflog.Log__c;
        }

        try {
            String data = NFMUtil.getRowDataStr(rowDataSFDC);
            String status = NFMUtil.sendToAWS612(data, NFMUtil.NFM614_ENDPOINT);
            System.debug('NFM614Log--status->' + status);

            if ('OK'.equals(status)) {
                logstr += status + '\n';
                rowDataSFDC.retry_cnt__c = 0;
            } else {
                logstr += 'status:' + status + '\n';
                if (rowDataSFDC.retry_cnt__c == null) rowDataSFDC.retry_cnt__c = 0;
                if (rowDataSFDC.retry_cnt__c < batch_retry_max_cnt) {
                    rowDataSFDC.retry_cnt__c++;
                    // LogAutoSendSchedule.logId = rowDataSFDC.Id;
                    LogAutoSendSchedule.assignOneMinute();
                }
                if (rowDataSFDC.retry_cnt__c >= batch_retry_max_cnt) {
                    rowDataSFDC.ErrorLog__c = 'status:' + status +
                                          '\n错误次数已经超过自动送信设定的最大次数，请手动送信';
                }
            }

        } catch (Exception ex) {
            // TODO IOException
            // 错误发生时
            logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
            if(!Test.isRunningTest()){
                // rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, ex, null);    //2022-06-24   zyh   注释：重发逻辑修改
                //2022-06-24   zyh   update   start
                if (rowDataSFDC.retry_cnt__c == null) rowDataSFDC.retry_cnt__c = 0;
                if (rowDataSFDC.retry_cnt__c < batch_retry_max_cnt){
                    rowDataSFDC.retry_cnt__c++;
                    // LogAutoSendSchedule.logId = rowDataSFDC.Id;
                    LogAutoSendSchedule.assignOneMinute();
                }
                if (rowDataSFDC.retry_cnt__c >= batch_retry_max_cnt){
                    rowDataSFDC.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowDataSFDC.ErrorLog__c+'错误次数已经超过自动送信设定的最大次数，请手动送信';
                }
                //2022-06-24   zyh   update   end
            }
        }
        iflog.Log__c = logstr;
        upsert iflog;
        upsert rowDataSFDC;
    }
    private static Map < id, List < rentalApplyEquipmentSet >> getRaesMap(List < String > raIdList) {
        List<Rental_Apply_Equipment_Set__c> raesList = [SELECT Id,Name,Rental_Apply__c FROM Rental_Apply_Equipment_Set__c WHERE Rental_Apply__c IN :raIdList];
        List < Id > raesIdList = new List < Id > ();
        for (Rental_Apply_Equipment_Set__c raes : raesList) {
            raesIdList.add(raes.Id);
        }
        // if (raesIdList.size() > 0) {
        Map < id, List < rentalApplyEquipmentSetDetail >> raesdMap = getRaesdMap(raesIdList);
        // }
        Map < id, List < rentalApplyEquipmentSet >> raesMap = new Map < id, List < rentalApplyEquipmentSet >> ();
        if (raesList.size() > 0) {
            for (Rental_Apply_Equipment_Set__c raes : raesList) {
                List < rentalApplyEquipmentSet > temp = raesMap.get(raes.Rental_Apply__c);
                if (temp == null) {
                    temp = new List < rentalApplyEquipmentSet > ();
                }
                rentalApplyEquipmentSet raesData = new rentalApplyEquipmentSet();
                raesData.equipmentName = raes.Name;
                raesData.Rental_Apply_Equipment_Set_Detail = raesdMap.get(raes.Id);
                temp.add(raesData);
                raesMap.put(raes.Rental_Apply__c, temp);
            }
        }
        return raesMap;
    }
    private static Map < id, List < rentalApplyEquipmentSetDetail >> getRaesdMap(List < String > raesIdList) {
        List<Rental_Apply_Equipment_Set_Detail__c> raesdList = [SELECT Id,Name,Fixture_Model_No__c,Queue_Number__c,Rental_Apply_Equipment_Set__c FROM Rental_Apply_Equipment_Set_Detail__c WHERE Rental_Apply_Equipment_Set__c IN :raesIdList AND Is_Body__c = TRUE];
        Map < id, List < rentalApplyEquipmentSetDetail >> raesdMap = new Map < id, List < rentalApplyEquipmentSetDetail >> ();
        if (raesdList.size() > 0) {
            for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList) {
                List < rentalApplyEquipmentSetDetail > temp = raesdMap.get(raesd.Rental_Apply_Equipment_Set__c);
                if (temp == null) {
                    temp = new List < rentalApplyEquipmentSetDetail > ();
                }
                rentalApplyEquipmentSetDetail raesdData = new rentalApplyEquipmentSetDetail();
                raesdData.assetModel = raesd.Fixture_Model_No__c;
                raesdData.queueNo = raesd.Queue_Number__c;
                raesdData.equipmentDetailName = raesd.Name;
                temp.add(raesdData);
                raesdMap.put(raesd.Rental_Apply_Equipment_Set__c, temp);
            }
        }
        return raesdMap;
    }
           
}