/**
 * 前提、Eventには、Event__cへの参照Idがあります。
 * ここはEvent__cを更新することを禁止
 * ①．Event__cを新規更新時、 ==> Eventに
 * ②．Event__cにはもしEventへの参照Idがある場合（日報一覧のinit時mappingしたしかない、init時Event__cデータをinsertする）
 */
trigger XinEventC2Event on Event__c (after delete, after insert, after update, before insert, before update) {
    
    //deloitte-zhj 20231124 本地化导入 start
    if((!Test.isRunningTest())&&System.Label.ByPassTrigger.contains(UserInfo.getUserId())){
        return;
    }
    //deloitte-zhj 20231124 本地化导入 end
    
    if (Trigger.isBefore) {
        // isSchedule絡みの項目を設定
        for (Event__c ec : Trigger.new) {
            // isScheduleフラグ設定
            if (Trigger.isInsert) {
                Date compareDate = null;
                if (ec.SyncCreatedDate__c != null && ec.SyncCreatedDate__c < System.now()) {
                    compareDate = Date.valueOf(ec.SyncCreatedDate__c);
                } else {
                    compareDate = Date.valueOf(System.now());
                }
                if (ec.ActivityDate__c > compareDate) {
                    ec.IsScheduled__c = true;
                }
            }
            
            if (ec.IsScheduled__c) {
                if (Trigger.isInsert) {
                    ec.IsScheduled_StartDateTime__c = ec.StartDateTime__c;
                    ec.IsScheduled_EndDateTime__c = ec.EndDateTime__c;
                    ec.IsScheduled_Location__c = ec.Location__c;
                    ec.IsScheduled_Subject__c = ec.Subject__c;
                }
            } else {
                ec.IsScheduled_StartDateTime__c = null;
                ec.IsScheduled_EndDateTime__c = null;
                ec.IsScheduled_Location__c = null;
                ec.IsScheduled_Subject__c = null;
            }
            if(ec.Subject__c == null || ec.Subject__c == ''){
                ec.Subject__c = ec.Activity_Purpose__c;
            }
        }
    /*
    // Account_ID__cとCampaign_ID__cをセット
        List<String> accList = new List<String>();
        List<String> campList = new List<String>();
        for (Event__c ec : Trigger.new) {
            // 想定：whatidがあれば必ずLocationもある
            if (!String.isBlank(ec.whatid__c)) {
                if (ec.whatid__c.startsWith('001')) {
                    accList.add(ec.Location__c);
                }
                if (ec.whatid__c.startsWith('701')) {
                    campList.add(ec.Location__c);
                }
            }
        }
        // 逆引き
        Map<String, List<String>> accMap = new Map<String, List<String>>();
        Map<String, List<String>> campMap = new Map<String, List<String>>();
        if (accList.size() > 0) accMap = ControllerUtil.getAccsByName(accList);
        if (campList.size() > 0) campMap = ControllerUtil.getCampsByName(campList);
        
        for (Event__c ec : Trigger.new) {
            if (ec.Free_Input__c) {
                ec.whatid__c = null;
                ec.Account_ID__c = null;
                ec.Campaign_ID__c = null;
            } else {
                if (!String.isBlank(ec.whatid__c)) {
                    if (ec.whatid__c.startsWith('001')) {
                        // 逆引きの結果は一件のみ、且つその結果はwhatidと同じの場合、対応するIDをセット
                        if (accMap.get(ec.Location__c) != null && accMap.get(ec.Location__c).size() == 1 && accMap.get(ec.Location__c).get(0) == ec.whatid__c) {
                            ec.Account_ID__c = ec.whatid__c;
                            ec.Campaign_ID__c = null;
                        } else {
                            // add error
                        }
                    }
                    if (ec.whatid__c.startsWith('701')) {
                        // 逆引きの結果は一件のみ、且つその結果はwhatidと同じの場合、対応するIDをセット
                        if (campMap.get(ec.Location__c) != null && campMap.get(ec.Location__c).size() == 1 && campMap.get(ec.Location__c).get(0) == ec.whatid__c) {
                            ec.Account_ID__c = null;
                            ec.Campaign_ID__c = ec.whatid__c;
                        } else {
                            // add error
                        }
                    }
                } else {
                    ec.Account_ID__c = null;
                    ec.Campaign_ID__c = null;
                }
            }
        }
        
        // メアド設定
        List<String> accIds = new List<String>();
        for (Event__c ec : Trigger.new) {
            if (Trigger.isInsert
                    || Trigger.isUpdate && Trigger.oldMap.get(ec.Id).get('Account_ID__c') != ec.Account_ID__c) {
                if (!String.isBlank(ec.Account_ID__c)) accIds.add(ec.Account_ID__c);
            }
        }
        
        Map<String, Account> BMap = new Map<String, Account>();
        Map<String, Account> SBMap = new Map<String, Account>();
        if (accIds.size() > 0) {
            List<Account> accs = ControllerUtil.selectBossMailAddr(accIds);
            for (Account acc : accs) {
                BMap.put(acc.Id, acc);
                SBMap.put(acc.Id, acc);
            }
        }
        
        for (Event__c ec : Trigger.new) {
            if (String.isBlank(ec.Account_ID__c)) {
                ec.Boss_Mail__c = null;
                ec.Sub_Boss_Mail__c = null;
                ec.Boss_Name__c = null;
                ec.Sub_Boss_Name__c = null;
            } else {
                if (BMap.containsKey(ec.Account_ID__c)) {
                    Account a = BMap.get(ec.Account_ID__c);
                    ec.Boss_Mail__c = Parent.Boss__r.Email;
                    ec.Boss_Name__c = Parent.Boss__r.Name;
                }
                if (SBMap.containsKey(ec.Account_ID__c)) {
                    Account a = SBMap.get(ec.Account_ID__c);
                    ec.Sub_Boss_Mail__c = Parent.Sub_Boss__r.Email;
                    ec.Sub_Boss_Name__c = Parent.Sub_Boss__r.Name;
                }
            }
        }
        */
    // after
    } else {
        
        // ------------------------nextEvent処理------------------------
        
        if (!Trigger.isDelete) {
            List<String> nextIds = new List<String>();
            
            for (Event__c ec : Trigger.new) {
                // nextEvent ids 作成
                if (Trigger.isInsert && ec.nextPlanDate__c != null) {
                    nextIds.add(ec.Id);
                }
                if (Trigger.isUpdate) {
                    Event__c oldec = new Event__c();
                    oldec = Trigger.oldMap.get(ec.Id);
                    if (ec.nextPlanDate__c != null
                        && (ec.nextPlanTimePurpose__c != oldec.get('nextPlanTimePurpose__c')
                        || ec.nextPlanDate__c != oldec.get('nextPlanDate__c'))) {
                        nextIds.add(ec.Id);
                    }
                }
            }
            
            if (nextIds.size() > 0) {
                Map<ID, Event> nextEventUpsertMap = new Map<ID, Event>();
                for (Event ne : [select Id, NextEventC_ID__c, EventC_ID__c from Event where NextEventC_ID__c in :nextIds]){
                    nextEventUpsertMap.put(ne.NextEventC_ID__c, ne);
                }
                
                Map<String, String> checkEventCMap = new Map<String, String>();
                for (Event__c nec : [select Id from Event__c where Id in :nextIds and Daily_Report__r.Status__c != '承認' and Daily_Report__r.Status__c != '非承認']){
                    checkEventCMap.put(nec.Id, nec.Id);
                }
                
                List<Event> save_eventsPla = new List<Event>();
                
                for (Event__c ec : Trigger.new) {
                    // 承認、非承認の時、nextEvent処理なし
                    if (!checkEventCMap.containsKey(ec.Id)) continue;
                    
                    Event nextEvent = new Event();
                    if (nextEventUpsertMap.containskey(ec.id)) {
                        nextEvent = nextEventUpsertMap.get(ec.id);
                    }
                    
                    // EventC_ID__c がある場合、upsert対象外にする
                    if (!String.isBlank(nextEvent.EventC_ID__c)) continue;
                    
                    // nextPlanTimePurpose__cの分割
                    List<String> nextTimePurpose = ec.nextPlanTimePurpose__c.split(',');
                    String planStartHourText = '';
                    String planStartMinuteText = '';
                    String planEndHourText = '';
                    String planEndMinuteText = '';
                    String planPurposeText = '';
                    if(nextTimePurpose.size() >= 5){
                        planStartHourText = nextTimePurpose[0];
                        planStartMinuteText = zeroFill(nextTimePurpose[1]);
                        planEndHourText = nextTimePurpose[2];
                        planEndMinuteText = zeroFill(nextTimePurpose[3]);
                        planPurposeText = '';
                        for (Integer i = 4; i < nextTimePurpose.size() - 1; i++) {
                            planPurposeText += nextTimePurpose[i] + ',';
                        }
                        planPurposeText += nextTimePurpose[nextTimePurpose.size() - 1];
                    }
                    
                    nextEvent.Subject = planPurposeText;
                    nextEvent.StartDateTime = Datetime.newInstance(ec.nextPlanDate__c.year(), ec.nextPlanDate__c.month(), ec.nextPlanDate__c.day(), Integer.valueOf(planStartHourText), Integer.valueOf(planStartMinuteText), 0);
                    nextEvent.EndDateTime = Datetime.newInstance(ec.nextPlanDate__c.year(), ec.nextPlanDate__c.month(), ec.nextPlanDate__c.day(), Integer.valueOf(planEndHourText), Integer.valueOf(planEndMinuteText), 0);
                    nextEvent.ActivityDateTime = nextEvent.StartDateTime;
                    nextEvent.ActivityDate = ec.nextPlanDate__c;
                    nextEvent.BeforeActivityDate__c = ec.nextPlanDate__c;
                    nextEvent.Activity_Type2__c = ec.Activity_Type2__c;
                    nextEvent.Purpose_Type__c = ec.Purpose_Type__c;
                    nextEvent.Related_Opportunity1__c = ec.Related_Opportunity1__c;
                    nextEvent.Related_Opportunity1_ID__c = ec.Related_Opportunity1_ID__c;
                    nextEvent.Related_Service1__c = ec.Related_Service1__c;
                    nextEvent.Related_Service1_ID__c = ec.Related_Service1_ID__c;
                    nextEvent.Location = ec.Location__c;
                    nextEvent.Main_Visit_Location__c = ec.Main_Visit_Location__c;
                    nextEvent.NextEventC_ID__c = ec.Id;
                    nextEvent.whatid__c = ec.whatid__c;
            //zzm 20231026 start
                    nextEvent.Related_Opportunity4__c = ec.whatid__c;
                    nextEvent.Related_Opportunity4_ID__c = ec.Infrastructure_Project1__c;
                    //zzm 20231026 end
                    save_eventsPla.add(nextEvent);
                }
                // システム管理者権限で更新
                ControllerUtil.upsEvent(save_eventsPla);
            }
        }
        
        // ------------------------同期処理------------------------
        
        // 更新対象 Id をセット
        Map<Id, Event__c> eventCMap = new Map<Id, Event__c>();     // ①のデータ、同期対象
        Set<String> eventCIdSet = new Set<String>();               // ①のデータ、削除対象
        Map<Id, Event__c> eventC_eventMap = new Map<Id, Event__c>();          // ②のデータ
        String strAcache = '';
        if (Trigger.isDelete) {
            for (Event__c ec : Trigger.old) {
                eventCIdSet.add(ec.Id);
                if (ec.Event_ID__c != null && ec.Event_ID__c != '') eventC_eventMap.put(ec.Event_ID__c, ec);
            }
            // 削除対象のEvent
            ControllerUtil.delEvent(eventCIdSet, eventC_eventMap);
        } else {
            for (Event__c ec : Trigger.new) {
                Event__c oldec = new Event__c();
                if (Trigger.isUpdate) {
                    oldec = Trigger.oldMap.get(ec.Id);
                }
                
                if (Trigger.isInsert
                        || (Trigger.isUpdate
                            && (ec.DataLoader__c == null || ec.DataLoader__c == oldec.DataLoader__c)
                            && (ec.Subject__c != oldec.get('Subject__c')
                            || ec.StartDateTime__c != oldec.get('StartDateTime__c')
                            || ec.EndDateTime__c != oldec.get('EndDateTime__c')
                            || ec.Main_Visit_Location__c != oldec.get('Main_Visit_Location__c')
                            || ec.Activity_Type2__c != oldec.get('Activity_Type2__c')
                            || ec.Purpose_Type__c != oldec.get('Purpose_Type__c')
                            || ec.Location__c != oldec.get('Location__c')
                            || ec.Related_Opportunity1__c != oldec.get('Related_Opportunity1__c')
                            || ec.Related_Opportunity1_ID__c != oldec.get('Related_Opportunity1_ID__c')
                            || ec.Infrastructure_Project1__c != oldec.get('Infrastructure_Project1__c') //zzm 20231026
                            || ec.Related_Service1__c != oldec.get('Related_Service1__c')
                            || ec.Related_Service1_ID__c != oldec.get('Related_Service1_ID__c')
                            || ec.whatid__c != oldec.get('whatid__c')
                            || ec.Purpose_TypeFSE__c != oldec.get('Purpose_TypeFSE__c')
                            || ec.Purpose_TypeEscFSE__c != oldec.get('Purpose_TypeEscFSE__c')
                            || ec.Activity_Purpose__c != oldec.get('Activity_Purpose__c')
                            || ec.Activity_PurposeFSE__c != oldec.get('Activity_PurposeFSE__c')
                            || ec.Activity_PurposeEscFSE__c != oldec.get('Activity_PurposeEscFSE__c')
                            || ec.AppCdId__c != oldec.get('AppCdId__c')))) {
                    eventCMap.put(ec.Id, ec);

                    if (ec.Event_ID__c != null && ec.Event_ID__c != ''){
                            eventC_eventMap.put(ec.Event_ID__c, ec);
                        } 
                }
            }
            // 同期対象のEvent
            ControllerUtil.upsEventC2Event(eventCMap, eventC_eventMap);
        }
    }
    
    /** 0埋め処理　 */
    private String zeroFill(String str){
        if(str.length() == 2){
            return str;
        }
        else{
            return '0' + str;
        }    
    }
}