global without sharing class FixtureRemindSnapshotBatch implements Database.Batchable<sObject>, Database.Stateful {
    global List<String> errorList = new List<String>();
    global Integer allCount = 0;
    global Integer doneCount = 0;

    private ScBean scB;

    global Database.QueryLocator start(Database.BatchableContext bc) {
        Integer i = 0;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;
        i ++;

        Datetime dt = System.now();
        scB = setSc('FixtureRemindSnapshotSchedule');
        if (System.Test.isRunningTest() == false) {
            for(CronTrigger ct : [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name =: scB.scName]) {
                System.abortJob(ct.Id);
            }
            system.schedule(scB.scName, scB.scTime, new FixtureRemindSnapshotSchedule());
        }
        String formattedDate = dt.format('YYYY-MM-dd');
        String query = 'SELECT Id FROM OlympusCalendar__c WHERE IsWorkDay__c > 0 AND Date__c = ' + formattedDate;
        System.debug(query);
        return Database.getQueryLocator(query);
    }

    public ScBean setSc(String baseName) {
        Datetime dt = Datetime.now();
        // 2021-12-30 format修改
        // Integer year = Integer.valueOf(dt.format('YYYY'));
        Integer year = Integer.valueOf(dt.format('yyyy'));
        Integer month = Integer.valueOf(dt.format('MM'));
        Integer day = Integer.valueOf(dt.format('dd'));
        Integer hour = Integer.valueOf(dt.format('HH'));
        Integer min = Integer.valueOf(dt.format('mm'));
        ScBean b = new ScBean();
        if (hour == 17 && min >= 30) {
            dt = Datetime.now().addDays(1);
            // year = Integer.valueOf(dt.format('YYYY'));
            year = Integer.valueOf(dt.format('yyyy'));
            month = Integer.valueOf(dt.format('MM'));
            day = Integer.valueOf(dt.format('dd'));
            hour = Integer.valueOf(dt.format('HH'));
            min = Integer.valueOf(dt.format('mm'));
            b.scName = baseName + '001';
            b.scTime = '0 ' + '0' + ' ' + '9' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else if (hour < 9) {
            b.scName = baseName + '001';
            b.scTime = '0 ' + '0' + ' ' + '9' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else if (hour < 11) {
            b.scName = baseName + '002';
            b.scTime = '0 ' + '30' + ' ' + '11' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else if (hour < 13) {
            b.scName = baseName + '003';
            b.scTime = '0 ' + '0' + ' ' + '13' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else if (hour < 14) {
            b.scName = baseName + '004';
            b.scTime = '0 ' + '0' + ' ' + '14' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else if (hour < 15) {
            b.scName = baseName + '005';
            b.scTime = '0 ' + '0' + ' ' + '15' + ' ' + day + ' ' + month + ' ? ' + year;
        }
        else {
            b.scName = baseName + '006';
            b.scTime = '0 ' + '30' + ' ' + '17' +' ' + day + ' ' + month + ' ? ' + year;

        }
        return b;
    }

    global void execute(Database.BatchableContext BC, list<OlympusCalendar__c> ocList) {
        // allCount += 3;
        allCount += 35;
        if(ocList.isEmpty()){
            return;
        }
        Savepoint sp = Database.setSavepoint();
        try {
            FixtureRemindUtil frUtil = new FixtureRemindUtil();
            frUtil.init();
            FixtureRemindSnapshot__c frsNorth = frUtil.createSnapshotRecord('北方');
            FixtureRemindSnapshot__c frsSouth = frUtil.createSnapshotRecord('南方');
            FixtureRemindSnapshot__c frsEast = frUtil.createSnapshotRecord('华东');

            //update by rentx 20210719 start
            // insert new List<FixtureRemindSnapshot__c> {frsNorth, frsSouth, frsEast};
            // doneCount += 3;
            FixtureRemindForAgencyRequestController col = new FixtureRemindForAgencyRequestController();
            col.makeData();
            List<FixtureRemindSnapshot__c> slist = new List<FixtureRemindSnapshot__c>();
            for (String str : FixtureRemindForAgencyRequestController.BSC_ADDR_LIST) {
                if (str != '合计') {
                    FixtureRemindSnapshot__c shot = col.createSnapshotRecord(str);
                    if (shot != null) {
                        slist.add(shot);                        
                    }
                }
            }
            slist.add(frsEast);
            slist.add(frsSouth);
            slist.add(frsNorth);
            insert slist;
            doneCount += 35;
            //update by rentx 20210719 end
            
        }
        catch (Exception e) {
            Database.rollback(sp);
            errorList.add(e.getMessage() + '\n' + e.getStackTraceString());
            System.debug(LoggingLevel.ERROR, e.getMessage() + '\n' + e.getStackTraceString());
            throw e;
        }
    }

    global void finish(Database.BatchableContext BC) {
        UpdateRentalApplyBatch.removeOtherSc('FixtureRemindSnapshotSchedule', scB.scName);
        if (allCount != doneCount || errorList.size() > 0) {
            BatchEmailUtil be = new BatchEmailUtil();
            String[] toList = new String[]{};
            String title = '首页通知快照更新失败';
            String[] ccList = new String[]{};
            for (OrgWideEmailAddress tmpEmailObj : [SELECT Id, Address, DisplayName
                    FROM OrgWideEmailAddress
                    WHERE DisplayName like 'BatchNotify']) {
                toList.add(tmpEmailObj.Address);
            }
            be.failedMail(toList, ccList, title, String.join(this.errorList, '\n'), allCount, doneCount, errorList.size());
            be.send();
        }
    }

    public Class ScBean {
        public String scName;
        public String scTime;
    }
}