global class InventoryTaskAndEmailBatch implements Schedulable, Database.Batchable<sObject> {

    public String YYYYMM = null;

    global void execute(SchedulableContext sc) {
        Database.executeBatch(new InventoryTaskAndEmailBatch());
    }

    global InventoryTaskAndEmailBatch() {
        Datetime now = Datetime.now();
        YYYYMM = now.format('YYYYMM');
    }

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator([SELECT Id, Email, RoleName_wave__c FROM User WHERE Profile.Name = '2B2_备品中心检测&仓库管理(照片)' AND IsActive = true]);
    }

    global void execute(Database.BatchableContext BC, list<User> scope) {

        // 只有每个Q第二个月的最后一天才执行，2、5、8、11
        if(!Test.isRunningTest()){
            Date today = Date.today();
            Integer month = today.month();
            if (month != 2 && month != 5 && month != 8 && month != 11) {
                return;
            }

            Integer numberOfDays = Date.daysInMonth(today.year(), today.month());
            Date lastDayOfMonth = Date.newInstance(today.year(), today.month(), numberOfDays);
            if (today != lastDayOfMonth) {
                return;
            }
        }

        // 北京备品中心人员
        List<User> bjUserList = new List<User>();
        // 上海备品中心人员
        List<User> shUserList = new List<User>();
        // 广州备品中心人员
        List<User> gzUserList = new List<User>();
        for (User uTemp : scope) {
            if (uTemp.RoleName_wave__c == '备品中心北方管理成员') {
                bjUserList.add(uTemp);
            } else if (uTemp.RoleName_wave__c == '备品中心华东管理成员') {
                shUserList.add(uTemp);
            } else if (uTemp.RoleName_wave__c == '备品中心南方管理成员') {
                gzUserList.add(uTemp);
            }
        }

        // 办事处人员
        List<User> userProvinceList = new List<User>();
        List<Inventory_User_Permission__mdt> usrList = [SELECT InventoryUser__c, Label FROM Inventory_User_Permission__mdt WHERE NOT Label like '%备品中心'];
        if (!usrList.isEmpty() && usrList.size() > 0) {
            // inventoryUserList
            for (Inventory_User_Permission__mdt uTemp : usrList) {
                Id[] usrArray = uTemp.InventoryUser__c.split(',');
                List<User> uTempList = [SELECT Id, Email, Work_Location__c FROM User WHERE Id In :usrArray];
                userProvinceList.addAll(uTempList);
            }
        }

        // 盘点检查计划
        List<RecordType> inventoryTaskId = [select Id from RecordType where SobjectType = 'task__c' AND Name = '盘点检查计划'];
        // 温湿度检查计划
        List<RecordType> temperatureHumidityTaskId = [select Id from RecordType where SobjectType = 'task__c' AND Name = '温湿度检查计划'];
        // 邮件发送人
        OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = 'olympus@prec-tech.com'];

        // 产生任务
        List<task__c> insertTaskList = new List<task__c>();
        // 产生邮件
        List<Messaging.SingleEmailMessage> emails = new List<Messaging.SingleEmailMessage>();
        // 北京备品中心
        for (User u : bjUserList) {
            // 盘点检查计划
            task__c tTemp1 = setTask(inventoryTaskId[0].Id, u, '盘点检查计划提醒_' + YYYYMM + '_北京 备品中心');
            // 温湿度检查计划
            task__c tTemp2 = setTask(temperatureHumidityTaskId[0].Id, u, '温湿度检查计划提醒_' + YYYYMM + '_北京 备品中心');
            insertTaskList.add(tTemp1);
            insertTaskList.add(tTemp2);

            // 盘点检查计划
            Messaging.SingleEmailMessage mail1 = setEmail(owea.get(0).Id, u, '盘点检查计划');
            // 温湿度检查计划
            Messaging.SingleEmailMessage mail2 = setEmail(owea.get(0).Id, u, '温湿度检查计划');
            emails.add(mail1);
            emails.add(mail2);
        }

        // 上海备品中心
        for (User u : shUserList) {
            // 盘点检查计划
            task__c tTemp1 = setTask(inventoryTaskId[0].Id, u, '盘点检查计划提醒_' + YYYYMM + '_上海 备品中心');
            // 温湿度检查计划
            task__c tTemp2 = setTask(temperatureHumidityTaskId[0].Id, u, '温湿度检查计划提醒_' + YYYYMM + '_上海 备品中心');
            insertTaskList.add(tTemp1);
            insertTaskList.add(tTemp2);

            // 盘点检查计划
            Messaging.SingleEmailMessage mail1 = setEmail(owea.get(0).Id, u, '盘点检查计划');
            // 温湿度检查计划
            Messaging.SingleEmailMessage mail2 = setEmail(owea.get(0).Id, u, '温湿度检查计划');
            emails.add(mail1);
            emails.add(mail2);
        }

        // 广州备品中心
        for (User u : gzUserList) {
            // 盘点检查计划
            task__c tTemp1 = setTask(inventoryTaskId[0].Id, u, '盘点检查计划提醒_' + YYYYMM + '_广州 备品中心');
            // 温湿度检查计划
            task__c tTemp2 = setTask(temperatureHumidityTaskId[0].Id, u, '温湿度检查计划提醒_' + YYYYMM + '_广州 备品中心');
            insertTaskList.add(tTemp1);
            insertTaskList.add(tTemp2);

            // 盘点检查计划
            Messaging.SingleEmailMessage mail1 = setEmail(owea.get(0).Id, u, '盘点检查计划');
            // 温湿度检查计划
            Messaging.SingleEmailMessage mail2 = setEmail(owea.get(0).Id, u, '温湿度检查计划');
            emails.add(mail1);
            emails.add(mail2);
        }

        // 办事处 办事处没有温湿度盘点计划
        for (User u : userProvinceList) {
            // 盘点检查计划
            task__c tTemp1 = setTask(inventoryTaskId[0].Id, u, '盘点检查计划提醒_' + YYYYMM + '_' + u.Work_Location__c);
            insertTaskList.add(tTemp1);

            // 盘点检查计划
            Messaging.SingleEmailMessage mail1 = setEmail(owea.get(0).Id, u, '盘点检查计划');
            emails.add(mail1);
        }
        
        if (!insertTaskList.isEmpty()) {
            insert insertTaskList;
        }

        if (!emails.isEmpty()) {
            Messaging.sendEmail(emails);
        }
    }

    global void finish(Database.BatchableContext BC) {
    }

    public static task__c setTask(String recordtypeId, User uTemp, String taskname) {
        task__c tTemp = new task__c();
        // 盘点检查计划
        tTemp.RecordTypeId = recordtypeId;
        // 任务区分
        tTemp.taskDifferent__c = '被动任务';
        // 所有人 ID
        tTemp.OwnerId = uTemp.Id;
        // 任务名称
        tTemp.Name = taskname;
        // End_Date__c 对应期限
        // Finish_Date__c 最终期限
        tTemp.PlanEndDate__c = Date.today().addMonths(1);
        // assignee__c 被分配者
        tTemp.assignee__c = uTemp.Id;

        return tTemp;
    }

    public static Messaging.SingleEmailMessage setEmail(String orgWideEmailAddressId, User uTemp, String emailName) {
        OrgWideEmailAddress[] owea = [select Id from OrgWideEmailAddress where Address = 'olympus@prec-tech.com'];
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {uTemp.Email}; 
        mail.setToAddresses(toAddresses);
        mail.setSaveAsActivity(false);
        mail.setOrgWideEmailAddressId(owea.get(0).Id);
        mail.setSubject(emailName + '邮件提醒');
        mail.setPlainTextBody('您有即将开始的' + emailName + '，请注意。');
        return mail;
    }
}