public without sharing class NFM602Controller {
    //点检报告数据推送接口
    private static final String LOG_TYPE = 'NFM602';
    // private static final String API = '/admin/api/ssi/save';
    private static final String API = '/admin/api/ssi/save';

    public Class GeData {
        List < SpotInspectionreport > spotInspectionreport;
    }
    public Class SpotInspectionreport {
        public String hospitalCd; //医院编码
        public String strategicDepartmenCd; //战略科室
        public String departmentCd; //科室编码
        public String contractCd; //合同编码
        public String ContractStattus; //合同状态
        public String contractStartDate; //合同起始日期
        public String contractEndDate; //合同结束日期
        public Decimal contractEquipQty; //合同设备量
        public String spotCheckBatch; //点检批次
        public String spotCheckDate; //点检日期
        public String checkStartDate; //检查开始时间
        public String checkEndDate; //检查结束时间
        public String spotCheckPerson; //点检人
        public String spotCheckUnifiedAuthId; //点检人统一平台Id
        public Decimal spotCheckEquipTotalQty; //点检设备总数
        public Decimal spotCheckAbnormalQty; //点检不正常设备数
        public ListOfAbnormalDevices[] ListOfAbnormalDevicesInfo; //点检不正常设备列表
    }
    //点检不正常设备列表
    public class ListOfAbnormalDevices {
        public String equipmentModel; //设备型号
        public String equipmentCd; //机身号
        public String problemDesc; //问题描述
    }
    //正常调用
    @future(callout = true)
    public static void callout(String iflog_Id, List < String > reportIdList) {
        BatchIF_Log__c iflog = [Select Id, Name, Log__c, ErrorLog__c from BatchIF_Log__c where Id =: iflog_Id];
        executeNotFuture(iflog, reportIdList);
    }
    public static void executeNotFuture(BatchIF_Log__c iflog, List < String > reportIdList) {
        Datetime nowDT = Datetime.now();
        String nowStr = nowDT.format('yyyyMMddHHmmss');
        List < Inspection_Report__c > inspectReportList = [select id,
            Strategic_Department__r.Management_Code__c,
            Strategic_Department__r.Management_Code_Auto__c,
            Hospital__r.Management_Code__c,
            Department__r.Management_Code__c,
            Contract__r.Maintenance_Contract_No_F__c,
            Contract__r.Contract_Start_Date__c,
            Contract__r.Contract_End_Date__c,
            Contract__r.New_equipment_quantity1__c,
            Contract__r.Estimate_Asset_Cnt__c,
            Contract__r.Effective_Status__c,
            Contract__r.Department__r.Management_Code__c,
            Contract__r.Department_Class__r.Management_Code_Auto__c,
            Contract__r.Department_Class__r.Management_Code__c,
            spotCheckBatch__c,
            Inspection_Date__c,
            Inspection_StartTime__c,
            Inspection_EndTime__c,
            Reporter__c,
            Reporter__r.Employee_No__c,
            Inspection_asset_number__c,
            Failourassetnumber__c
            from Inspection_Report__c where id in: reportIdList
        ];
        if (iflog != null) {
            iflog.Type__c = LOG_TYPE;
            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;
        }
        List < SpotInspectionreport > gedList = new List < SpotInspectionreport > ();
        BatchIF_Log__c rowData = null;
        String logstr = iflog.Log__c + ' ' + 'NumberOfRecord=' + inspectReportList.size() + '\n';
        try {
            Map < Id, List < ListOfAbnormalDevices >> itemmap = new Map < Id, List < ListOfAbnormalDevices >> ();
            //设备状态 ok、ng 只查询ng状态的设备   只查询对应id的设备
            List < Inspection_Item__c > itemList = [select
                Inspection_ReportId__c,
                AssetId__c,
                AssetId__r.Product_Serial_No__c,
                AssetId__r.Product2.Asset_Model_No__c,
                SerialNumber__c, 
                Diagnosis__c,
                Product_Manual__r.Asset_Model_No__c,
                SerialNo_Manual__c  
                from Inspection_Item__c
                where ItemStatus__c = 'NG'
                And Inspection_ReportId__c in: reportIdList
            ];
            for (Inspection_Item__c item: itemList) {
                List < ListOfAbnormalDevices > devicesList = itemmap.get(item.Inspection_ReportId__c);
                if (devicesList == null) {
                    devicesList = new List < ListOfAbnormalDevices > ();
                }

                ListOfAbnormalDevices abnormal = new ListOfAbnormalDevices();
                abnormal.equipmentModel = item.AssetId__r.Product2.Asset_Model_No__c; //设备型号
                abnormal.equipmentCd = item.SerialNumber__c;//机身号
                if (String.isBlank(item.AssetId__c)) {
                    abnormal.equipmentModel = item.Product_Manual__r.Asset_Model_No__c;//设备型号
                    abnormal.equipmentCd = item.SerialNo_Manual__c;//产品编码（手写）
                }
                
                abnormal.problemDesc = item.Diagnosis__c;
                devicesList.add(abnormal);
                itemmap.put(item.Inspection_ReportId__c, devicesList);
            }
            for (Inspection_Report__c inspetReport: inspectReportList) {
                // 点检报告书 科室
                String departmentCd = inspetReport.Department__r.Management_Code__c;
                if (String.isBlank(departmentCd)) {
                    // 维修合同 科室
                    departmentCd = inspetReport.Contract__r.Department__r.Management_Code__c;
                }

                // 点检报告书 战略科室 
                String strategicDepartmenCd = inspetReport.Strategic_Department__r.Management_Code__c;
                if (String.isBlank(strategicDepartmenCd)) {
                    // 维修合同 战略科室
                    strategicDepartmenCd = inspetReport.Contract__r.Department_Class__r.Management_Code__c;
                }

                SpotInspectionreport ged = new SpotInspectionreport();
                ged.hospitalCd = inspetReport.Hospital__r.Management_Code__c; //医院编码
                ged.strategicDepartmenCd = strategicDepartmenCd;//inspetReport.Strategic_Department__r.Management_Code_Auto__c; //战略科室
                ged.departmentCd = departmentCd;//inspetReport.Department__r.Management_Code__c; //科室编码
                ged.contractCd = inspetReport.Contract__r.Maintenance_Contract_No_F__c; //合同编码
                ged.ContractStattus = inspetReport.Contract__r.Effective_Status__c; //合同状态
                ged.contractStartDate = NFMUtil.formatDate2StrDateTime(inspetReport.Contract__r.Contract_Start_Date__c); //合同起始日期
                ged.contractEndDate = NFMUtil.formatDate2StrDateTime(inspetReport.Contract__r.Contract_End_Date__c); //合同结束日期
                ged.contractEquipQty = inspetReport.Contract__r.Estimate_Asset_Cnt__c; //合同设备量
                ged.spotCheckBatch = inspetReport.spotCheckBatch__c; //点检批次
                ged.spotCheckDate = NFMUtil.formatDate2StrDateTime(inspetReport.Inspection_Date__c); //点检日期
                ged.checkStartDate = NFMUtil.formatDateTime2Str(inspetReport.Inspection_StartTime__c); //检查开始时间
                ged.checkEndDate = NFMUtil.formatDateTime2Str(inspetReport.Inspection_EndTime__c); //检查结束时间
                ged.spotCheckPerson = inspetReport.Reporter__r.Employee_No__c; //点检人
                ged.spotCheckUnifiedAuthId = inspetReport.Reporter__r.Employee_No__c; //统一平台管理编码
                ged.spotCheckEquipTotalQty = inspetReport.Inspection_asset_number__c; //点检设备总数
                ged.spotCheckAbnormalQty = inspetReport.Failourassetnumber__c; //点检不正常设备数
                ged.ListOfAbnormalDevicesInfo = itemmap.get(inspetReport.Id); //点检不正常设备列表
                gedList.add(ged);
            }
            logstr += '\nend';
            if (gedList.size() > 0) {
                GeData ged = new GeData();
                ged.spotInspectionreport = gedList;
                //生成BatchLog日志,记录发送情况
                rowData = NFMUtil.makeRowData(iflog, LOG_TYPE, ged);
                //insert rowData;
                execute(rowData, iflog);
            }
            if (Test.isRunningTest()) {
                Integer num = Integer.valueOf('TestError');
            }
        } catch (Exception ex) {
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getStackTraceString());
            logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\n';
        }
        if (rowData != null) {
            upsert rowData;
        }
        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.MessageGroupNumber__c + ' 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.sendToAWS(data, API);
            System.debug('NFM602Log--status->' + status);
            if ('OK'.equals(status)) {
                logstr += status + '\n';
                rowDataSFDC.retry_cnt__c = 0;
            } else {
                // 异常重发
                rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, null, status);
            }

            if (Test.isRunningTest()) {
                Integer num = Integer.valueOf('TestError');
            }
        } catch (Exception ex) {
            // TODO IOException
            // エラーが発生した場合
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getMessage());
            System.debug(Logginglevel.ERROR, LOG_TYPE + iflog.Name + ':' + ex.getStackTraceString());
            //logstr += ex.getMessage();
            iflog.ErrorLog__c += ex.getMessage() + '\n';
            iflog.ErrorLog__c += ex.getStackTraceString() + '\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.assignOneMinute();
            // }
            // if (rowDataSFDC.retry_cnt__c >= batch_retry_max_cnt) {
            //     rowDataSFDC.ErrorLog__c = ex.getMessage() + '\n' + ex.getStackTraceString() + '\n' + rowDataSFDC.ErrorLog__c + '错误次数已经超过自动送信设定的最大次数，请手动送信';
            // }
            rowDataSFDC = NFMUtil.LogAutoSend(rowDataSFDC, ex, null);
        }
        iflog.Log__c = iflog.Log__c + logstr;
    }

    public static void sendToAWS(Map < Id, Id > idMap) {
        System.debug('idMap--->'+idMap);
        // key-->维修合同Id,value--->点检报告书Id集合
        Map < Id, Set < Id >> tempIdMap = new Map < Id, Set < Id >> ();
        for (Id inspection_ReportId: idMap.keySet()) {
            Id contractId = idMap.get(inspection_ReportId);
            Set < Id > idSet = new Set < Id > ();
            if (tempIdMap.containsKey(contractId)) {
                idSet = tempIdMap.get(contractId);
            }
            idSet.add(inspection_ReportId);
            tempIdMap.put(contractId, idSet);
        }

        System.debug('tempIdMap--->'+tempIdMap);
        List < Repair__c > repairList = [
            SELECT Id, VM_Maintenance_Contract__c, Maintenance_Contract__c, MaintenanceContractType__c
            FROM Repair__c
            WHERE Maintenance_Contract__c IN: tempIdMap.keySet() 
            // AND MaintenanceContractType__c = '服务合同'
            AND Maintenance_Contract__r.RecordType.DeveloperName = 'NewMaintenance_Contract'
            AND RepairSubOrder__c != ''
        ];
        if (repairList.size() > 0) { 
            Map<String,String> reportIdMap = new Map<String,String>();
            for (Repair__c repair: repairList) {
                // 获取维修合同Id
                String contractId = repair.Maintenance_Contract__c;
                for (Id tempId: tempIdMap.get(contractId)) {
                    String reportId = String.valueOf(tempId);
                    reportIdMap.put(reportId, reportId);
                }
            }

            List < String > reportIdList = reportIdMap.values();//new List < String > ();
            System.debug('reportIdList--->'+reportIdList);
            BatchIF_Log__c iflog = new BatchIF_Log__c();
            iflog.Type__c = LOG_TYPE;
            iflog.Log__c  = 'callout start\n';
            insert iflog;
            NFM602Controller.callout(iflog.Id, reportIdList);
        }

        

    }
}