/**
 * 前提：朝で実行するので、Date__c <= :toDate、期首日も 4/1 その日から 4/1 になる
 */
global class UpdateUserTextColBatch implements Database.Batchable<sObject> {
    global final String testUserId;

    Boolean IsNeedExecute = false; // 2021-03-08  mzy  WLIG-BYHD79  SFDC环境batch合并调查  是否符合执行条件

    /**
     * コンスタント、パラメータを受け取る
     */
    global UpdateUserTextColBatch(String testUserId) {
        this.testUserId = testUserId;
    }

    global UpdateUserTextColBatch() {
        this.testUserId = null;
    }

    // 2021-03-08  mzy  WLIG-BYHD79  SFDC环境batch合并调查  start
    global UpdateUserTextColBatch(Boolean NeedExecute) {
        this.IsNeedExecute = NeedExecute;
    }
    global UpdateUserTextColBatch(String testUserId,Boolean NeedExecute) {
        this.testUserId = testUserId;
        this.IsNeedExecute = NeedExecute;
    }
    // 2021-03-08  mzy  WLIG-BYHD79  SFDC环境batch合并调查  end


    /**
     * startには、queryを実行、ユーザーを検索
     */
    global Database.QueryLocator start(Database.BatchableContext BC) {
        String query = 'Select Id, Fiscal_Start_Date__c, Fiscal_Start_Date_from_May__c, Use_Start_Date__c from User';
        if (String.isBlank(testUserId) == false) {
            query += ' where Id =\'' + testUserId + '\'';
        }
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<SObject> uList) {
        for (SObject u : uList) {
            User usr = (User) u;
            Date toDate = Date.today();
            Date fromDate4 = usr.Fiscal_Start_Date__c;
            if (usr.Use_Start_Date__c != null && usr.Use_Start_Date__c > usr.Fiscal_Start_Date__c) {
                fromDate4 = usr.Use_Start_Date__c;
            }

            usr.Fiscal_Workdays__c = decimal.valueOf(getOlympusWorkDayCount(fromDate4, toDate));
            /***** CHAN-AZABMC ****** 2018/06/01 ********
             **** 到本月的工作日（今年度）
             **** 到本周的工作日（今年度）
            *********************************************/
            Date thisMonthToDate = Date.newInstance(toDate.year(), toDate.month(), 1);
            Date thisWeekToDate = toDate.toStartofWeek().addDays(1);
            if (usr.Use_Start_Date__c == null || (usr.Use_Start_Date__c != null && usr.Use_Start_Date__c < thisMonthToDate)) {
                usr.Fiscal_Workdays_thisMonth__c = decimal.valueOf(getOlympusWorkDayCount(thisMonthToDate, toDate));
            } else {
                usr.Fiscal_Workdays_thisMonth__c = decimal.valueOf(getOlympusWorkDayCount(usr.Use_Start_Date__c, toDate));
            }
            if (usr.Use_Start_Date__c == null || (usr.Use_Start_Date__c != null && usr.Use_Start_Date__c < thisWeekToDate)) {
                usr.Fiscal_Workdays_thisWeek__c = decimal.valueOf(getOlympusWorkDayCount(thisWeekToDate, toDate));
            } else {
                usr.Fiscal_Workdays_thisWeek__c = decimal.valueOf(getOlympusWorkDayCount(usr.Use_Start_Date__c, toDate));
            }

            usr.This_Month_SS_day__c = getThisMonthSSday(toDate);
            Integer jintian = getOlympusWorkDayCount(toDate, toDate);
            Integer zuotian = getOlympusWorkDayCount(toDate.addDays(-1), toDate.addDays(-1));
            usr.Jintian_WorkingDay__c = (jintian > 0);
            usr.Zuotian_WorkingDay__c = (zuotian > 0);

            if (toDate >= Date.newInstance(2014, 4, 1)) {
                // 来年度はいらない
            } else {
                Date fromDate5 = usr.Fiscal_Start_Date_from_May__c;
                if (usr.Use_Start_Date__c != null && usr.Use_Start_Date__c > usr.Fiscal_Start_Date_from_May__c) {
                    fromDate5 = usr.Use_Start_Date__c;
                }
                AggregateResult[] cal5 = [Select Count(Id) cnt From OlympusCalendar__c Where Date__c >= :fromDate5 And Date__c <= :toDate And IsWorkDay__c = 1];
                usr.Fiscal_Workdays_From_May__c = decimal.valueOf((Integer) cal5[0].get('cnt'));
            }

            //いらないはず、UpdateRentalApplyEquipmentSetBatch で計算しています
            //bp2            AggregateResult[] points = [select SUM(Foul_Points__c) fp
            //                        from Rental_Apply_Equipment_Set__c
            //                        where Rental_Apply__r.OwnerId = :usr.Id and Foul_Points__c > 0
            //                          and AND Cancel_Select__c = False];
            //bp2            usr.Foul_Points__c = points[0].get('fp') == null ? 0 : decimal.valueOf(String.valueOf(points[0].get('fp')));
        }

        /* 2018-12-10 CHAN-B6W86D 根据权限集进行权限设置  start*/

        Map <Id, User> uMap = new Map <Id, User>();
        for (SObject u : uList) {
            User newUser = (User) u;
            newUser.Download_right__c          = false;
            newUser.ProductCostReferable__c    = false;
            newUser.ENDOPARTNERReferable__c    = false;
            newUser.P002_OCM_Act__c            = false;
            newUser.P002_Agent_Act__c          = false;
            newUser.SI_ProfessionalAuth__c     = false;
            newUser.Plan_report_permission__c  = false;
            newUser.Group_purchse_dept__c      = false;
            newUser.Create_dashboard__c        = false;
            newUser.EditCompetitorAsset__c     = false;
            uMap.put(newUser.Id, newUser);
        }
        list<PermissionSetAssignment> PermissionSetAssignmentList =
            [SELECT Id, AssigneeId, PermissionSetId FROM PermissionSetAssignment
             where AssigneeId in : uList
             and (PermissionSetId = : system.Label.PermissionSet_Createdashboard_ID
                                    or PermissionSetId = : system.Label.PermissionSet_ENDOPARTNER_ID
                                            or PermissionSetId = : system.Label.PermissionSet_Group_purchse_dept_ID
                                                    or PermissionSetId = : system.Label.PermissionSet_P002_Agent_ID
                                                            or PermissionSetId = : system.Label.PermissionSet_P002_OCM_ID
                                                                    or PermissionSetId = : system.Label.PermissionSet_Plan_report_permission_ID
                                                                            or PermissionSetId = : system.Label.PermissionSet_ProductCost_ID
                                                                                    or PermissionSetId = : system.Label.PermissionSet_Report_ID
                                                                                            or PermissionSetId = : system.Label.PermissionSet_SI_ID
                                                                                                    or PermissionSetId = : system.Label.PermissionSet_EditCompetitorAsset_ID  // CHAN-B7K8K8 2018/12/18 
                                                                                                    )];

        for (PermissionSetAssignment temPSA : PermissionSetAssignmentList) {
            User currentUser = uMap.get(temPSA.AssigneeId);
            if (currentUser == null) {
                continue;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_Createdashboard_ID)) {
                currentUser.Create_dashboard__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_ENDOPARTNER_ID)) {
                currentUser.ENDOPARTNERReferable__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_Group_purchse_dept_ID)) {
                currentUser.Group_purchse_dept__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_P002_Agent_ID)) {
                currentUser.P002_Agent_Act__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_P002_OCM_ID)) {
                currentUser.P002_OCM_Act__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_Plan_report_permission_ID)) {
                currentUser.Plan_report_permission__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_ProductCost_ID)) {
                currentUser.ProductCostReferable__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_Report_ID)) {
                currentUser.Download_right__c = true;
            }
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_SI_ID)) {
                currentUser.SI_ProfessionalAuth__c = true;
            }
            // CHAN-B7K8K8 2018/12/18 start
            if (temPSA.PermissionSetId.equals(system.Label.PermissionSet_EditCompetitorAsset_ID)) {
                currentUser.EditCompetitorAsset__c = true;
            }
            // CHAN-B7K8K8 2018/12/18 end
        }
        /* 2018-12-10 CHAN-B6W86D 根据权限集进行权限设置  end*/
        update uList;
    }

    global void finish(Database.BatchableContext BC) {
        // 今回はやることないです

        //2021-03-08  mzy  WLIG-BYHD79  SFDC环境batch合并调查  start
        if(!Test.isRunningTest() &&IsNeedExecute==true){
            //batch里调用下一个batch时，希望跟原有的Schedule里面传的条数保持一致
            Id execBTId = Database.executebatch(new TaskStatusUpdateBatch(true));
        }
        //2021-03-08  mzy  WLIG-BYHD79  SFDC环境batch合并调查 end

    }

    public static Integer getOlympusWorkDayCount(Date fromDate, Date toDate) {
        AggregateResult[] calAggResult = [Select Count(Id) cnt From OlympusCalendar__c Where Date__c >= :fromDate And Date__c <= :toDate And IsWorkDay__c = 1];
        Integer workDayCount = (Integer) calAggResult[0].get('cnt');
        return workDayCount;
    }
    public static Date getThisMonthSSday(Date thisMonth) {
        Date mon1stDate = Date.newInstance(thisMonth.year(), thisMonth.month(), 1);
        Integer SSBacth_Execute_Day = Integer.valueOf(System.Label.SSBacth_Execute_Day);
        List<OlympusCalendar__c> ssDay = [Select Date__c From OlympusCalendar__c Where Date__c >= :mon1stDate And IsWorkDay__c = 1 order by Date__c asc limit :SSBacth_Execute_Day];
        // TODO xudan ssDay.size() >= SSBacth_Execute_Day の判断は必要？
        // Limit3なのに、実際データは2件しかないなど⇒データ不備、わざとExceptionを出したほうがいい？
        return ssDay[SSBacth_Execute_Day - 1].Date__c;
    }
}