/**
 * 2022-01-20 create
 * 
 * 1.决裁状态更新为不可用的时候（驳回、删除），清除学会上的决裁信息。
 * 2.opd计划上的引用字段达到上线，不能使用公式关联决裁的状态，在决裁状态更新时，更新OPD计划上的文本字段。
 */
public without sharing class ApplicationForCAHandler extends Oly_TriggerHandler  {
    private Map<Id, Application_for_Conference_Adjudication__c> newMap;
    private Map<Id, Application_for_Conference_Adjudication__c> oldMap;
    private List<Application_for_Conference_Adjudication__c> newList;
    private List<Application_for_Conference_Adjudication__c> oldList;

    private static Map<String, String> states;
    private static Map<String, String> cities;
    
    public ApplicationForCAHandler() {
        this.newMap = (Map<Id, Application_for_Conference_Adjudication__c>) Trigger.newMap;
        this.oldMap = (Map<Id, Application_for_Conference_Adjudication__c>) Trigger.oldMap;
        this.newList = (List<Application_for_Conference_Adjudication__c>) Trigger.new;
        this.oldList = (List<Application_for_Conference_Adjudication__c>) Trigger.old;
    }

    protected override void beforeUpdate() {
        // 更新时判断是否更新了绑定的学会，如果绑定多个学会且不是赞助会时，清空绑定关系
        clean_binding();
        clean_campaign();
        update_campaign();
    }

    protected override void afterUpdate() {
        // opd计划的引用字段达到上线，决裁状态需要在触发器里更新
        update_status_on_opd();
    }

    // 更新时判断是否更新了绑定的学会，如果绑定多个学会且不是赞助会时，清空绑定关系
    private void clean_binding() {
        Map<String, String> app_cam_binds = new Map<String, String>();
        for (Application_for_Conference_Adjudication__c app : this.newList) {
            Application_for_Conference_Adjudication__c old_app = this.oldMap.get(app.Id);
            if (String.isNotBlank(old_app.Num__c) && !old_app.Num__c.equals(app.Num__c) && app.MeetingType__c != '赞助会') {
                app_cam_binds.put(old_app.Id, old_app.Num__c);
            }
        }
        if (app_cam_binds.size() > 0) {
            List<Campaign> cams = [select Id, MeetingApprovedNo__c, Meeting_Approved_No__c from Campaign where Meeting_Approved_No__c in :app_cam_binds.keySet() and Num__c in :app_cam_binds.values()];
            if (cams != null && cams.size() > 0) {
                for (Campaign cam : cams) {
                    cam.MeetingApprovedNo__c = null;
                    cam.Meeting_Approved_No__c = null;
                }
                update cams;
            }
        }
    }

    // 审批不通过的时候 清空会议和OPD计划上的决裁信息
    private void clean_campaign() {
        List<String> approved_nos = new List<String>();
        for (Application_for_Conference_Adjudication__c app : this.newList) {
            if (app.ProcessState__c == '驳回' || 
                app.ProcessState__c == '终止申请' || 
                app.ProcessState__c == '取消' ||
                app.ProcessState__c == '删除') {
                    approved_nos.add(app.Id);
            }
        }
        if (approved_nos.size() > 0) {
            List<Campaign> campaigns = [select Id, MeetingApprovedNo__c, Meeting_Approved_No__c from Campaign where Meeting_Approved_No__c in :approved_nos];
            if (campaigns != null && campaigns.size() > 0) {
                for (Campaign cam : campaigns) {
                    cam.MeetingApprovedNo__c = null;
                    cam.Meeting_Approved_No__c = null;
                }
                update campaigns;
            }
            List<OPDPlan__c> opdplans = [select Id, Approved_No__c, Approved_Status__c from OPDPlan__c where Approved_No__c in :approved_nos];
            if (opdplans != null && opdplans.size() > 0) {
                for (OPDPlan__c plan : opdplans) {
                    plan.Approved_No__c = null;
                    plan.Approved_Status__c = null;
                }
                update opdplans;
            }
        }
    }

    // 审批通过的时候，更新学会信息
    private void update_campaign() {
        List<String> app_ids = new List<String>();
        Map<String, Application_for_Conference_Adjudication__c> app_nos = new Map<String, Application_for_Conference_Adjudication__c>();
        for (Application_for_Conference_Adjudication__c app : this.newList) { 
            if (app.ProcessState__c == '审批成功') {
                app.Approved_Date__c = Date.today();
                app_ids.add(app.Id);
                // 补充决裁
                if (app.IsSupplemental__c) {
                    app_nos.put(app.MeetingApprovedNo__c, app);
                }
            }
        }
        Map<String, Campaign> wait_upd_campaigns = new Map<String, Campaign>();
        if (app_ids.size() > 0) {
            List<Campaign> campaigns = [select Id, Num__c, MeetingApprovedNo__c, Meeting_Approved_No__c from Campaign where Meeting_Approved_No__c in :app_ids and Meeting_Type__c != '赞助会'];
            if (campaigns.size() > 0) {
                for (Campaign cam : campaigns) {
                    Application_for_Conference_Adjudication__c app = this.newMap.get(cam.Meeting_Approved_No__c);
                    if (app.IsSupplemental__c) {
                        cam = update_info_from_app(cam, app);
                    }
                    wait_upd_campaigns.put(cam.Id, cam);
                }
            }
        }
        if (app_nos.size() > 0) {
            List<Campaign> campaigns = [select Id, Num__c, MeetingApprovedNo__c, Meeting_Approved_No__c from Campaign where MeetingApprovedNo__c in :app_nos.keySet()];
            if (campaigns.size() > 0) {
                for (Campaign cam : campaigns) {
                    Application_for_Conference_Adjudication__c app = app_nos.get(cam.MeetingApprovedNo__c);
                    // 当决裁上的会议编号和学会的编号相同时，更新状态
                    if (String.isNotBlank(app.Num__c) && app.Num__c == cam.Num__c) {
                        cam.Meeting_Approved_No__c = app.Id;
                        cam = update_info_from_app(cam, app);
                    }
                    wait_upd_campaigns.put(cam.Id, cam);
                }
            }
        }
        if (wait_upd_campaigns.size() > 0) {
            update wait_upd_campaigns.values();
        }
    }

    // 决裁状态更新的时候，更新opd计划上的决裁状态
    private void update_status_on_opd() {
        List<String> app_ids = new List<String>();
        for (Application_for_Conference_Adjudication__c app : this.newList) {
            Application_for_Conference_Adjudication__c old_app = this.oldMap != null ? this.oldMap.get(app.Id) : new Application_for_Conference_Adjudication__c();
            if (String.isNotBlank(app.ProcessState__c) && String.isNotBlank(old_app.ProcessState__c) && app.ProcessState__c != old_app.ProcessState__c){
                app_ids.add(app.Id);
            }
        }
        if (app_ids.size() > 0) {
            List<OPDPlan__c> opdplans = [select Id, Approved_No__c, Approved_Status__c from OPDPlan__c where Approved_No__c in :app_ids];
            if (opdplans != null && opdplans.size() > 0) {
                for (OPDPlan__c plan : opdplans) {
                    plan.Approved_Status__c = this.newMap.get(plan.Approved_No__c).ProcessState__c;
                }
                update opdplans;
            }
        }
    }

    // 更新决裁的信息到学会上
    private Campaign update_info_from_app(Campaign cam, Application_for_Conference_Adjudication__c app) {
        cam.StartDate                        = app.StartDate__c;
        cam.EndDate                          = app.EndDate__c;
        cam.Budget_Type__c                   = app.BudgetType__c;
        cam.OfficeCategory__c                = app.OfficeCategory__c;
        cam.Meeting_Type__c                  = app.MeetingType__c;

        cam.WorkshopPlace__c                 = app.WorkshopPlace__c;
        cam.HostName__c                      = app.HostName__c;
        cam.cooperatorCompany__c             = app.CooperatorCompany__c;
        cam.Convening_Participants_Num__c    = app.ConveningParticipantsNum__c;

        // OBPM对接 新增字段
        cam.Expected_Olympus_Attendance__c   = app.ExpectedOlympusAttendance__c;
        cam.Expected_Hcp_Attendance__c       = app.ExpectedHcpAttendance__c;
        cam.SponsorshipCategory__c           = app.SponsorshipCategory__c;
        cam.IsPaidToSponsor__c               = app.IsPaidToSponsor__c;
        // cam.Activity_Type_Name__c            = app.ActivityTypeName__c;
        cam.Activity_Type_Name__c            = app.Type_of_adjudication_meeting__c;
        // 这里需要额外加操作
        cam.State_Master__c                  = StateCityUtil.get_state(app.StateMaster__c);                 
        cam.City_Master__c                   = StateCityUtil.get_city(app.CityMaster__c);

        return cam;
    }
}