global class CBFbatch implements Database.Batchable<SObject> , Database.Stateful {
    public String query;
    public String cbfId;
    private BatchIF_Log__c iflog;

    global CBFbatch() {
        this.query = query;
    }
    global CBFbatch(String cbfId) {
        this.query = query;
        this.cbfId = cbfId;
    }
    global Database.QueryLocator start(Database.BatchableContext bc) {
          //添加邮件提醒 start
          system.debug('执行start');
          iflog = new BatchIF_Log__c();
          iflog.Type__c = 'CBFbatch';
          iflog.Log__c  = 'CBFbatch start\n';
          iflog.ErrorLog__c = '';
          insert iflog;
          //添加邮件提醒 end
        query = 'select id,name,cbf_execute__c from Account where Is_Active_Formula__c = \'有效\' and Acc_Record_Type__c = \'病院\' and cbf_execute__c != 1';
        if (cbfId != null && cbfId != '') {
            query += ' and id = :cbfId';
        }else {
            query += ' and id in(select Hospital__c from Repair__c  WHERE Cumulative_Uses__c != null AND Cumulative_Times__c != null)';
        }
        System.debug('执行结果：'+Database.getQueryLocator(query));
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, list<Account> AccountList) {
        List<String> accountIds = new List<String>();
        for (Account acc : AccountList) {
            accountIds.add(acc.id);
        }
        iflog.Log3__c = JSON.serialize(accountIds);
        update iflog;
        List<Repair__c> repairList = [SELECT Id,
                                             Name,
                                            Cumulative_Uses__c, 
                                            Cumulative_Times__c, 
                                            Repair_Ordered_Date__c, 
                                            Cycle_between_failure__c, 
                                            Product_Unique_Value__c,
                                            Hospital__c
                                             FROM Repair__c 
                                             WHERE Cumulative_Uses__c != null 
                                             AND Cumulative_Times__c != null 
                                             AND Hospital__c in: accountIds];
        // 去重
        Map<String,Integer> uniqueMap = new Map<String, Integer>();
        for (Repair__c repair : repairList) {
            if (!uniqueMap.containsKey(repair.Product_Unique_Value__c)) {
                uniqueMap.put(repair.Product_Unique_Value__c, 1);
            }else {
                uniqueMap.put(repair.Product_Unique_Value__c, uniqueMap.get(repair.Product_Unique_Value__c) + 1);
            }
        }
        // List<String> uniqueList = new List<String>(uniqueMap.values());
            List<String> uniqueList = new List<String>();
            for (String key : uniqueMap.keySet()) {
                Integer value = uniqueMap.get(key);
                if (value == 1) {
                    continue; // 如果值等于1，则跳过当前循环，不将键存入uniqueList中
                }
                uniqueList.add(key);
            }
        try {
            if (uniqueList.size() > 0 && uniqueList.size() <= 180) {
                   // 定义一个列表来存储查询结果
                    List<Repair__c> resultList = new List<Repair__c>();
                    List<Asset> AssetList = new List<Asset>();
                    // 根据去重后的数据去取修理中的通电回数，通电时间
                    List<Repair__c> rLists = [select id,
                                                    name,
                                                    Cumulative_Uses__c,
                                                    Cumulative_Times__c,
                                                    Repair_Ordered_Date__c,
                                                    Cycle_between_failure__c,
                                                    Delivered_Product__c,
                                                    Product_Unique_Value__c 
                                                    from Repair__c 
                                                    where 
                                                    Cumulative_Uses__c != null 
                                                    and Cumulative_Times__c != null 
                                                    and Product_Unique_Value__c in:uniqueList  
                                                    ORDER BY Repair_Ordered_Date__c Asc];
                    iflog.Log2__c += JSON.serialize(accountIds)+'处理组合总数量：'+uniqueList.size();
                    update iflog;
                    list<Account> AccountUpdateList = new List<Account>();
                    for (String acc : accountIds) {
                        Account a = new Account();
                        a.id = acc;
                        a.cbf_execute__c = 1;
                        AccountUpdateList.add(a);
                    }
                    // 通过map 对相同Product_Unique_Value__c 组合的数据进行分组
                    Map<String, List<Repair__c>> repairMap = new Map<String, List<Repair__c>>();
                    for(Repair__c r : rLists) {
                        if(repairMap.containsKey(r.Product_Unique_Value__c)) {
                            repairMap.get(r.Product_Unique_Value__c).add(r);
                        } else {
                            List<Repair__c> tempList = new List<Repair__c>();
                            tempList.add(r);
                            repairMap.put(r.Product_Unique_Value__c, tempList);
                        }
                    }
                    // 取出每组的值进行计算
                    for(String key : repairMap.keySet()) {  
                        // 定义一个变量来记录cbf
                        List<String> cbflist = new List<String>();
                        Integer prev = 0;
                        List<Repair__c> rList = repairMap.get(key);
                        if (rList.size() > 1) {
                            for (Integer i = 0; i < rList.size(); i++) {
                                // 当前的通电回数
                                Integer curr = Integer.valueOf(rList[i].Cumulative_Uses__c);
                                // 处理负数 若两数相减为负数 则返回 0
                                Integer diff = i == 0 ? 0 : Math.max(curr - prev, 0);

                                if (diff == 0 && i!=0) {
                                    diff = curr;
                                }

                                rList[i].Cycle_between_failure__c = diff;

                                cbflist.add(String.valueOf(diff));

                                prev = curr == 0 ? prev : curr;
                            }

                            Asset asset = new Asset();
                            asset.id = rList[0].Delivered_Product__c;
                            asset.Cumulative_Uses__c = prev;
                            AssetList.add(asset);
                            
                            System.debug('最后一次：'+prev);
                            resultList.addAll(rList);
                            System.debug('处理后的结果：'+cbflist);
                        }else if (rList.size() == 1){
                            rList[0].Cycle_between_failure__c = 0;
                            resultList.addAll(rList);
                            Asset asset = new Asset();
                            asset.id = rList[0].Delivered_Product__c;
                            asset.Cumulative_Uses__c = rList[0].Cumulative_Uses__c;
                            AssetList.add(asset);
                        }
                        // iflog.Log__c += '/'+key;
                    }
                    Database.SaveResult[] saveTenderResults = Database.update(resultList, false);
                    Database.SaveResult[] saveTenderResults2 = Database.update(AssetList, false); 
                    Database.SaveResult[] saveTenderResults3 = Database.update(AccountUpdateList, false); 
            }else {
                iflog.Log4__c += JSON.serialize(accountIds)+'处理组合总数量：'+uniqueList.size();
                update iflog;
            }
        } catch (Exception e) {
              // 记录错误消息
              String errorMessage = e.getMessage()+'===========》报错组合'+uniqueList+'/n===========>报错医院'+accountIds;
              iflog.ErrorLog__c += errorMessage;
              update iflog;
              return;
        }
    }

    global void finish(Database.BatchableContext BC) {
       // 添加邮件提醒 start
       iflog.Log__c += '\nCBFbatch end';
    //    String tmp = iflog.ErrorLog__c;
    //    if (tmp.length() > 65000) {
    //        tmp = tmp.substring(0, 65000);
    //        tmp += ' ...have more lines...';
    //        iflog.ErrorLog__c = tmp;
    //    }
       update iflog;
       //添加邮件提醒 end
    }

}