/* 备品智能化 add by dzk
   备品申请根据OPD计划排序进行排序
   测试类：OPDAutomaticSortBatchTest // 20231230 ljh 
*/
global class RentalAutomaticSortBatch implements Database.Batchable<sObject>,Database.Stateful {
    private final List<String> sdcName = null;
    private BatchIF_Log__c iflog;
    public Boolean onlyMyselefy = true;
    public Boolean withoutDate = false;
    public Date myStartDate;
    public Date myEndDate;
    global RentalAutomaticSortBatch(){
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'RentalAutomaticSortBatch';
        iflog.Log__c  = 'RentalAutomaticSortBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
    }

    global RentalAutomaticSortBatch(List<String> str){
        sdcName = str;
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'RentalAutomaticSortBatch';
        iflog.Log__c  = 'RentalAutomaticSortBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
    }

    global RentalAutomaticSortBatch(Boolean only, Boolean without){
        this.onlyMyselefy = only;
        this.withoutDate = without;
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'RentalAutomaticSortBatch';
        iflog.Log__c  = 'RentalAutomaticSortBatch start\n';
        iflog.ErrorLog__c = '';
        insert iflog;
    }
    // global RentalAutomaticSortBatch(Date startDate,Date endDate,Boolean only){
    //     this.myStartDate = startDate;
    //     this.myEndDate = endDate;
    //     this.onlyMyselefy = only;
    // }
    
    global Database.QueryLocator start(Database.BatchableContext BC){
        
        String sql = 'SELECT Id,Name,type__c FROM opp2AuxiliarySort__c ';
        sql += ' WHERE Id != null ';
        if(sdcName <> null){
            sql += 'AND Name IN :sdcName ';
        }
        sql += ' AND (type__c = 2 OR type__c = 11)';
        sql += ' ORDER BY type__c';
        System.debug('=sql='+sql);
        return Database.getQueryLocator(sql);
    }

    global void execute(Database.BatchableContext BC, List<opp2AuxiliarySort__c> opp2AuxiliarySortList) {
        try{

            Date today = Date.today();
            // 获取从次月14日至再次月13日的日期
            Date startDate = today.addMonths(1).toStartOfMonth().addDays(13);
            Date endDate = today.addMonths(2).toStartOfMonth().addDays(12);
            Map<String,OPDPlan__c> opdAgainMap = New Map<String,OPDPlan__c>(); 
            // OPD计划排序完成后,备品申请再根据销售本部进行排序
            List<Rental_Apply__c>  applyAgainSelectList = new  List<Rental_Apply__c>();
            if (!withoutDate) {
                applyAgainSelectList = [SELECT Id,
                                         CreatedDate,
                                         // OPD_OrderNum__c,//OPD排序
                                         User_Salesdept__c,//销售本部
                                         demo_purpose2__c,
                                         OPDPlan__r.RentalApplyNum__c,
                                         OPDPlan__r.OPDLendSort__c,
                                         Request_approval_time__c,
                                         Request_shipping_day__c
                                    FROM Rental_Apply__c
                                    WHERE OPDPlan__r.OPDLendSort__c != null
                                    AND User_Salesdept__c =: opp2AuxiliarySortList[0].Name
                                    AND OPDPlan__r.OPDPlan_ImplementDate__c >=: startDate
                                    AND OPDPlan__r.OPDPlan_ImplementDate__c <=: endDate
                                    AND OPDPlan__r.If_AutoSort__c = 1 
                                    AND RA_Status__c IN ('草案中','申请中','已批准')
                                    ORDER BY demo_purpose2__c,
                                    OPDPlan__r.OPDLendSort__c ASC,
                                             Request_shipping_day__c ASC,
                                             Request_approval_time__c ASC];
                iflog.Log__c += '\nbenbu:'+opp2AuxiliarySortList[0].Name;
                System.debug('***benbu:'+opp2AuxiliarySortList[0].Name);
            }else{
                // 历史数据
                applyAgainSelectList = [SELECT Id,
                                             CreatedDate,
                                             // OPD_OrderNum__c,//OPD排序
                                             User_Salesdept__c,//销售本部
                                             demo_purpose2__c,
                                             OPDPlan__r.RentalApplyNum__c,
                                             OPDPlan__r.OPDLendSort__c,
                                             Request_approval_time__c,
                                             Request_shipping_day__c
                                        FROM Rental_Apply__c
                                        WHERE OPDPlan__r.OPDLendSort__c != null
                                        AND User_Salesdept__c =: opp2AuxiliarySortList[0].Name
                                        AND OPDPlan__r.If_AutoSort__c = 1 
                                        // AND RA_Status__c IN ('草案中','申请中','已批准')
                                        ORDER BY demo_purpose2__c,
                                        OPDPlan__r.OPDLendSort__c ASC,
                                                 Request_shipping_day__c ASC,
                                                 Request_approval_time__c ASC];
            iflog.Log__c += '\nbenbu:'+opp2AuxiliarySortList[0].Name;
            System.debug('***benbu:'+opp2AuxiliarySortList[0].Name);
            }
            List<RentalApplyComparator> sortableList = new List<RentalApplyComparator>();
            iflog.Log__c += applyAgainSelectList.size();
            if(applyAgainSelectList.size() > 0){
                for (Rental_Apply__c obj : applyAgainSelectList) {
                    sortableList.add(new RentalApplyComparator(obj));
                }

                sortableList.sort();

                List<Rental_Apply__c> sortedList = new List<Rental_Apply__c>();
                for (RentalApplyComparator comparator : sortableList) {
                    sortedList.add(comparator.customRen);
                }

                Map<String,Integer> renApplyAgainMap = new Map<String,Integer>();                                                              
                for(Rental_Apply__c renApplyBefore : sortedList){
                    renApplyAgainMap.put(renApplyBefore.User_Salesdept__c, 0);
                }                                                         
                for(Rental_Apply__c renApplyAgain : sortedList){
                    String saleSdept = renApplyAgain.User_Salesdept__c;
                    OPDPlan__c opd = new OPDPlan__c();
                    if(renApplyAgainMap.containsKey(saleSdept) && !opdAgainMap.containsKey(renApplyAgain.OPDPlan__c)){
                        opd.Id = renApplyAgain.OPDPlan__c;
                        opd.RentalApplyNum__c = renApplyAgainMap.get(saleSdept) + 1;
                        Integer numOPDPlan = Integer.valueOf(renApplyAgainMap.get(saleSdept) + 1);
                        renApplyAgainMap.put(saleSdept, numOPDPlan);
                        opdAgainMap.put(opd.Id, opd);
                    }
                }
            } 
            iflog.Log__c += '更新数:'+opdAgainMap.size();   
            if (opdAgainMap != null && opdAgainMap.size() > 0) {
                update opdAgainMap.values();
            } 
        }catch(Exception ex){
            iflog.ErrorLog__c = ex.getLineNumber()+'  行错误 :   '+ex.getMessage();
            return;
        }
        
    }

    global void finish(Database.BatchableContext BC) {
        iflog.Log__c += '\nRentalAutomaticSortBatch 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;
        if(!onlyMyselefy && !Test.isRunningTest()){
            Id execBTId = Database.executebatch(new OPDPlanMarkBatch(), 100);
        }
    }

    public class RentalApplyComparator implements Comparable {
    public Rental_Apply__c customRen;

        public RentalApplyComparator(Rental_Apply__c obj) {
            this.customRen = obj;
        }

        public Integer compareTo(Object renToCompare) {
            RentalApplyComparator compareToRen = (RentalApplyComparator)renToCompare;

            // 根据使用目的进行排序
            Integer returnValue = comparePurposeOrder(compareToRen.customRen.demo_purpose2__c, customRen.demo_purpose2__c);
            if (returnValue != 0) {
                return returnValue;
            }

            // 如果使用目的相同，按照OPD排序
            if (customRen.OPDPlan__r.OPDLendSort__c < compareToRen.customRen.OPDPlan__r.OPDLendSort__c) {
                returnValue = -1;
            } else if (customRen.OPDPlan__r.OPDLendSort__c > compareToRen.customRen.OPDPlan__r.OPDLendSort__c) {
                returnValue = 1;
            }
            if (returnValue != 0) {
                return returnValue;
            }

            if(customRen.demo_purpose2__c == '学会展会' && compareToRen.customRen.demo_purpose2__c == '学会展会'){
                // 如果OPD相同，按照希望到货日排序
                if (customRen.Request_shipping_day__c < compareToRen.customRen.Request_shipping_day__c) {
                    returnValue = -1;
                } else if (customRen.Request_shipping_day__c > compareToRen.customRen.Request_shipping_day__c) {
                    returnValue = 1;
                }
                if (returnValue != 0) {
                    return returnValue;
                }
            }

            // 如果希望到货日相同，按照批准日期排序
            if (customRen.Request_approval_time__c < compareToRen.customRen.Request_approval_time__c) {
                returnValue = -1;
            } else if (customRen.Request_approval_time__c > compareToRen.customRen.Request_approval_time__c){
                returnValue = 1;
            } 

            if (returnValue != 0) {
                return returnValue;
            }
            
            // 按照创建时间排序
            if (customRen.CreatedDate < compareToRen.customRen.CreatedDate) {
                returnValue = -1;
            } else if (customRen.CreatedDate > compareToRen.customRen.CreatedDate) {
                returnValue = 1;
            }
            if (returnValue != 0) {
                return returnValue;
            }
            return returnValue;
        }

        private Integer comparePurposeOrder(String purpose1, String purpose2) {
            // 定义使用目的的排序顺序
            Map<String, Integer> purposeOrderMap = new Map<String, Integer>{
                '学会展会' => 1,
                '已购待货' => 2,
                '新产品评价' => 3,
                '试用（有询价）' => 4,
                '试用（无询价）' => 4
            };

            // 获取使用目的的排序顺序
            Integer order1 = purposeOrderMap.containsKey(purpose1) ? purposeOrderMap.get(purpose1) : 5;
            Integer order2 = purposeOrderMap.containsKey(purpose2) ? purposeOrderMap.get(purpose2) : 5;
            // 如果使用目的不在定义的排序顺序内，默认按照字母顺序排序

            Integer returnValue = 0;
            if (order1 < order2) {
                returnValue = 1;
            } else if (order2 > order1){
                returnValue = -1;
            }
            return returnValue;
        }
    }
    
}