public without sharing class AgencyHospitalHandler extends Oly_TriggerHandler {
    private Map<Id, Agency_Hospital_Link__c> newMap;
    private Map<Id, Agency_Hospital_Link__c> oldMap;
    private List<Agency_Hospital_Link__c> newList;
    private List<Agency_Hospital_Link__c> oldList;

    public AgencyHospitalHandler() {
        this.newMap = (Map<Id, Agency_Hospital_Link__c>) Trigger.newMap;
        this.oldMap = (Map<Id, Agency_Hospital_Link__c>) Trigger.oldMap;
        this.newList = (List<Agency_Hospital_Link__c>) Trigger.new;
        this.oldList = (List<Agency_Hospital_Link__c>) Trigger.old;
    }

    protected override void beforeInsert() {
        beforeExecute();
        //AgencyHospital_Number_Summary(this.newList, this.oldMap);
    }

    protected override void beforeUpdate() {
        beforeExecute();
        shareAgency_Hospital_Link_ToRole(this.newList, this.oldMap);
    }

    protected override void afterInsert() {
        shareAgency_Hospital_Link_ToRole(this.newList, this.oldMap);
        AgencyHospital_Number_Summary(this.newList, this.oldMap);
    }

    protected override void afterUndelete() {
        shareAgency_Hospital_Link_ToRole(this.newList, this.oldMap);
        //AgencyHospital_Number_Summary(this.newList, this.oldMap);
    }

    //lt 20210824 start
    protected override void afterUpdate() {
        AgencyHospital_Number_Summary(this.newList, this.oldMap);
    }
    
    protected override void afterdelete() {
        AgencyHospital_Number_Summary(this.newList, this.oldMap);
    }
    //lt 20210824 end


    
    //protected override void beforeUpdate() {
    //    shareAgency_Hospital_Link_ToRole(this.newList);
    //}

    //Before処理
    private void beforeExecute() {
        Map<Id, List<Agency_Hospital_Link__c>> accMap = new Map<Id, List<Agency_Hospital_Link__c>>();
        for (Agency_Hospital_Link__c nObj : newList) {
            if(accMap.containsKey(nObj.Hospital__c)){
                nObj.Agency_ID__c = String.valueOf(nObj.Agency__c).substring(0, 15);
                nObj.Name = nObj.Hospital_Name_readonly__c;
                accMap.get(nObj.Hospital__c).add(nObj);
            }else{
                List<Agency_Hospital_Link__c> temp = new List<Agency_Hospital_Link__c>();
                nObj.Agency_ID__c = String.valueOf(nObj.Agency__c).substring(0, 15);
                nObj.Name = nObj.Hospital_Name_readonly__c;
                temp.add(nObj);
                accMap.put(nObj.Hospital__c,temp);
            }
            
        }

        // List<Account> accList = [select Id, Name from Account where id in :accMap.keySet()];
        // // for (Account acc : accList) {
        // //     Agency_Hospital_Link__c nObj = accMap.get(acc.Id);
        // //     nObj.Name = acc.name;
        // // }
        // for (Account acc : accList) {
        //     List<Agency_Hospital_Link__c> nObjList = accMap.get(acc.Id);
        //     for(Agency_Hospital_Link__c nObj : nObjList){
        //         nObj.Name = acc.name;
        //     }
        // }
    }

    /**
     * 设定 apex share to role
     * @param accId UserRoleとGroupを取得するため
     */
    /*
    private static void setAgency_Hospital_Link_Share(Id accId, List<Id> pList) {
        System.debug('accId:'+accId);
        Id grpId = MergeAgencyActivityBatch.accIdGrpIdMap(accId);
        List<Agency_Hospital_Link__Share> shareList = new List<Agency_Hospital_Link__Share>();
        Set<Id> sharePIdSet = new Set<Id>();
        for (Agency_Hospital_Link__Share share : [SELECT Id, ParentId
                FROM Agency_Hospital_Link__Share
                WHERE UserOrGroupId = :grpId]) {
            sharePIdSet.add(share.ParentId);
        }
        for (Id pId : pList) {
            if (sharePIdSet.contains(pId) == false) {
                Agency_Hospital_Link__Share apexShare = new Agency_Hospital_Link__Share(
                        RowCause = 'Manual',
                        ParentId = pId,
                        UserOrGroupId = grpId,
                        AccessLevel = 'Edit');
                shareList.add(apexShare);
            }
        }
        if (Test.isRunningTest() && grpId == null) {
            // 没有造 User 的旧Test 也让可以过
            return;
        }
        insert shareList;
    }
    */

    // private static void setAgency_Hospital_Link_Share(Id accId, List<Id> pList) {
    //     System.debug('accId:' + accId);
    //     Id grpId = MergeAgencyActivityBatch.accIdGrpIdMap(accId);
    //     if (grpId != null) {
    //         List<Agency_Hospital_Link__Share> shareList = new List<Agency_Hospital_Link__Share>();
    //         Set<Id> sharePIdSet = new Set<Id>();
    //         for (Agency_Hospital_Link__Share share : [SELECT Id, ParentId
    //                 FROM Agency_Hospital_Link__Share
    //                 WHERE UserOrGroupId = :grpId AND RowCause = 'Manual']) {
    //             sharePIdSet.add(share.ParentId);
    //         }
    //         for (Id pId : pList) {
    //             if (sharePIdSet.contains(pId) == false) {
    //                 Agency_Hospital_Link__Share apexShare = new Agency_Hospital_Link__Share(
    //                     RowCause = 'Manual',
    //                     ParentId = pId,
    //                     UserOrGroupId = grpId,
    //                     AccessLevel = 'Edit');
    //                 shareList.add(apexShare);
    //             }
    //         }
    //         if (Test.isRunningTest() && grpId == null) {
    //             // 没有造 User 的旧Test 也让可以过
    //             return;
    //         }
    //         insert shareList;
    //     }

    // }

    private static void setAgency_Hospital_Link_Share(List<Id> targetIdList,Map<Id, List<Id>> tmap){
        
            System.debug('传进来的targetIdList:' + targetIdList);
            System.debug('传进来的tmap:' + tmap);
            
            Map<Id,Id> grpIds = AgencyHospitalHandler.accIdGrpIdMap(targetIdList);

            //结果集合
            List<Agency_Hospital_Link__Share> shareList = new List<Agency_Hospital_Link__Share>();

            //一个供应商查出来对应的多个结果
            Map<Id,Set<Id>> shareMap = new Map<Id,Set<Id>>();

            //查出所有分享grpId的分享
            List<Agency_Hospital_Link__Share> ahList =[SELECT Id, ParentId,Parent.Agency__c
                    FROM Agency_Hospital_Link__Share
                    WHERE UserOrGroupId = :grpIds.values() AND RowCause = 'Manual'];

            for(Id accId : grpIds.keySet()){
                if (grpIds.get(accId) != null) {
                    
                    for (Agency_Hospital_Link__Share share : ahList) {

                        if(shareMap.containsKey(accId) && share.Parent.Agency__c == accId){

                            shareMap.get(accId).add(share.ParentId);

                        }else{

                            Set<Id> sharePIdSet = new Set<Id>();
                            sharePIdSet.add(share.ParentId);
                            shareMap.put(accId,sharePIdSet);

                        }
                        
                    }
    
                    if (Test.isRunningTest() && grpIds.get(accId) == null) {
                        // 没有造 User 的旧Test 也让可以过
                        return;
                    }       
                }
            }


            System.debug('shareMap====为'+shareMap);
            
            for (Id tId : tmap.keySet()) {
                for(Id pId : tmap.get(tId)){
                    // 因有的经销商医院没有共享给经销商 添加 !shareMap.containsKey(tId) XHL 20210818
                    if (!shareMap.containsKey(tId) || (shareMap.containsKey(tId) && shareMap.get(tId).contains(pId) == false)) {
                        Agency_Hospital_Link__Share apexShare = new Agency_Hospital_Link__Share(
                        RowCause = 'Manual',
                        ParentId = pId,
                        UserOrGroupId = grpIds.get(tId),
                        AccessLevel = 'Edit');
    
                        shareList.add(apexShare);
                    }
                }
            }
            

            System.debug('上传的List为'+shareList);
            insert shareList;
    }


    //返回一个Map<供应商Id,需要的Id>
    private static Map<Id, Id> accIdGrpIdMap;
    public static Map<Id,Id> accIdGrpIdMap(List<Id> accIds) {


        List<UserRole> roles = [SELECT Id, PortalAccountId
                    FROM UserRole
                    WHERE PortalRole = 'Worker'
                    AND PortalAccountId in :accIds];

        List<Id> Ids = new List<Id>();

        for(UserRole ur : roles){
            Ids.add(ur.Id);
        }

        List<Group> groups = [SELECT Id, RelatedId
                    FROM Group
                    WHERE Type = 'RoleAndSubordinates'
                    AND RelatedId = :Ids];

        for(Id accId : accIds){

            if (AgencyHospitalHandler.accIdGrpIdMap == null) { AgencyHospitalHandler.accIdGrpIdMap = new Map<Id, Id>(); }


            if (AgencyHospitalHandler.accIdGrpIdMap.get(accId) == null) {

                // List<UserRole> roles = [SELECT Id, PortalAccountId
                //         FROM UserRole
                //         WHERE PortalAccountId = :accId
                //         AND PortalRole = 'Worker'];

                Map<Id, Id> roleIdAccId = new Map<Id, Id>();
                for (UserRole ur : roles) {
                    roleIdAccId.put(ur.Id, ur.PortalAccountId);
                }

                // List<Group> groups = [SELECT Id, RelatedId
                //         FROM Group
                //         WHERE RelatedId = :roleIdAccId.keySet()
                //         AND Type = 'RoleAndSubordinates'];

                for (Group grp : groups) {
                    AgencyHospitalHandler.accIdGrpIdMap.put(roleIdAccId.get(grp.RelatedId), grp.Id);
                }
            }
        }
        return AgencyHospitalHandler.accIdGrpIdMap;
    }


    // afterInsert, afterUndelete
    /**
     * 一定要是同一经销商的
     * @param nList {Id, Agency__c}
     */
    /*
    public static void shareAgency_Hospital_Link_ToRole(List<Agency_Hospital_Link__c> nList) {
        Set<Id> targetAgencyIdSet = new Set<Id>();
        Map<Id, List<Id>> tMap = new Map<Id, List<Id>>();
        for (Agency_Hospital_Link__c nObj : nList) {
            targetAgencyIdSet.add(nObj.Agency__c);
            List<Id> tList = tMap.get(nObj.Agency__c);
            if (tList == null) {
                tList = new List<Id>();
            }
            tList.add(nObj.Id);
            tMap.put(nObj.Agency__c, tList);
        }
        system.debug('targetAgencyIdSet:'+targetAgencyIdSet);
        if (targetAgencyIdSet.size() > 0) {
            List<Id> targetIdList = new List<Id> (targetAgencyIdSet);
            System.assertEquals(1, targetIdList.size(), '一定要是同一经销商 [' + targetIdList[0] + ']');
            setAgency_Hospital_Link_Share(targetIdList[0], tMap.get(targetIdList[0]));
        }
    }
    */
    /*
    1.经销商医院新增 经销商活动对象 为真 创建 共享
    2.经销商医院变更 经销商活动对象 为真 判断 未共享 创建 共享
    3.经销商医院变更 经销商活动对象 由真变成假 判断 共享是否存在 ，存在删除
     */
    public static void shareAgency_Hospital_Link_ToRole(List<Agency_Hospital_Link__c> nList, Map<Id, Agency_Hospital_Link__c> oldMap) {
        Set<Id> targetAgencyIdSet = new Set<Id>();
        Map<Id, List<Id>> tMap = new Map<Id, List<Id>>();
        //Agency_Hospital_Link__c old = null;
        Map<Id, List<Id>> deleteShareMap = new  Map<Id, List<Id>>();
        for (Agency_Hospital_Link__c nObj : nList) {

            if (nObj.Agency_Campaign_Obj__c) {
                //1.经销商医院新增 经销商活动对象 为真 创建 共享
                //2.经销商医院变更 经销商活动对象 为真 判断 未共享 创建 共享
                targetAgencyIdSet.add(nObj.Agency__c);
                List<Id> tList = tMap.get(nObj.Agency__c);
                if (tList == null) {
                    tList = new List<Id>();
                }
                tList.add(nObj.Id);
                tMap.put(nObj.Agency__c, tList);

            } else {
                if (Trigger.isUpdate) {
                    if (nObj.Agency_Campaign_Obj__c != oldMap.get(nObj.Id).Agency_Campaign_Obj__c) {
                        //3.经销商医院变更 经销商活动对象 由真变成假 判断 共享是否存在 ，存在删除
                        List<Id> deleteShareIdList = new List<Id>();
                        if (deleteShareMap.containsKey(nObj.Agency__c)) {
                            deleteShareIdList = deleteShareMap.get(nObj.Agency__c);
                        }
                        deleteShareIdList.add(nObj.Id);
                        deleteShareMap.put(nObj.Agency__c, deleteShareIdList);
                    }
                }
            }

        }

        System.debug('targetAgencyIdSet:' + targetAgencyIdSet);
        if (targetAgencyIdSet.size() > 0) {
            List<Id> targetIdList = new List<Id> (targetAgencyIdSet);
            //System.assertEquals(1, targetIdList.size(), '一定要是同一经销商 [' + targetIdList[0] + ']');
            //setAgency_Hospital_Link_Share(targetIdList[0], tMap.get(targetIdList[0]));
            System.debug('拿到的tMap的长度========'+tMap.size());
            
            //2021/7/30 参数传map
            setAgency_Hospital_Link_Share(targetIdList,tMap);

        }

        if (deleteShareMap.size() > 0) {

            deleteAgency_Hospital_Link_Share(deleteShareMap);
        }
    }
    /**
     * 删除 经销商医院的共享权限
     * @Author   XHL
     * @DateTime 2021-07-01
     * @param    deleteShareMap [key=经销商Id，value= 经销商医院IdList]
     */
    public static void deleteAgency_Hospital_Link_Share(Map<Id, List<Id>> deleteShareMap) {
        // 经销商Id
        List<Id> dealerIdList = new List<Id>(deleteShareMap.keyset());
        // 待删除的共享权限的经销商医院的Id
        List<Id> deleteShareIdList = new List<Id>();
        for (Id accountId : deleteShareMap.keyset()) {
            deleteShareIdList.addAll(deleteShareMap.get(accountId));
        }

        // 获取经销商的用户角色
        List<UserRole> roles = [SELECT Id, PortalAccountId
                                FROM UserRole
                                WHERE PortalAccountId IN :dealerIdList
                                AND PortalRole = 'Worker'];
        Map<Id, Id> roleIdAccId = new Map<Id, Id>();
        for (UserRole ur : roles) {
            roleIdAccId.put(ur.Id, ur.PortalAccountId);
        }
        // 获取经销商的用户角色 所在的小组
        List<Id> groupIdList = new List<Id>();
        List<Group> groups = [SELECT Id, RelatedId
                              FROM Group
                              WHERE RelatedId = :roleIdAccId.keySet()
                                                AND Type = 'RoleAndSubordinates'];
        for (Group grp : groups) {
            groupIdList.add(grp.Id);
        }
        List<Agency_Hospital_Link__Share> deleteShareList = new List<Agency_Hospital_Link__Share>();
        for (Agency_Hospital_Link__Share share : [SELECT Id, ParentId
                FROM Agency_Hospital_Link__Share
                WHERE UserOrGroupId IN :groupIdList AND RowCause = 'Manual' AND AccessLevel = 'Edit' order by UserOrGroupId]) {
            if (deleteShareIdList.contains(share.ParentId)) {
                deleteShareList.add(share);
            }
        }
        if (deleteShareList.size() > 0) {
            delete deleteShareList;
        }

    }

    //public static Id accIdGrpIdMap(Id accId) {
    //    if (MergeAgencyActivityBatch.accIdGrpIdMap == null) { MergeAgencyActivityBatch.accIdGrpIdMap = new Map<Id, Id>(); }
    //    if (MergeAgencyActivityBatch.accIdGrpIdMap.get(accId) == null) {
    //        List<UserRole> roles = [SELECT Id, PortalAccountId
    //                                FROM UserRole
    //                                WHERE PortalAccountId = :accId
    //                                        AND PortalRole = 'Worker'];
    //        Map<Id, Id> roleIdAccId = new Map<Id, Id>();
    //        for (UserRole ur : roles) {
    //            roleIdAccId.put(ur.Id, ur.PortalAccountId);
    //        }
    //        List<Group> groups = [SELECT Id, RelatedId
    //                              FROM Group
    //                              WHERE RelatedId = :roleIdAccId.keySet()
    //                                                AND Type = 'RoleAndSubordinates'];
    //        for (Group grp : groups) {
    //            MergeAgencyActivityBatch.accIdGrpIdMap.put(roleIdAccId.get(grp.RelatedId), grp.Id);
    //        }
    //    }
    //    return MergeAgencyActivityBatch.accIdGrpIdMap.get(accId);
    //}


    //SWAG-C5XBY2  精琢科技  lt  2021-08-24  start
    public static void AgencyHospital_Number_Summary(List<Agency_Hospital_Link__c> sList,Map<Id, Agency_Hospital_Link__c> oldMap){

        List<String> cdeal = new List<String>();
        
        if(sList != null){
            for(Agency_Hospital_Link__c Obj : sList){
                // 修改  经销商医院数据 统计
                if(oldMap != null){
                    if (Obj.Agency_Campaign_Obj__c != oldMap.get(Obj.Id).Agency_Campaign_Obj__c || (System.Label.onlyupdate == '1' && UserInfo.getUserId() == System.Label.jingzhuo)){//niwu-00510000005sEEMAA2-应改为 005C60000001iK1IAI 查找用户精琢技术 
                        cdeal.add(Obj.Agency__c);   //变化的经销商
                    }      
            }
                // 新建  经销商医院数据 统计
                else{
                    if(Obj.Agency_Campaign_Obj__c == true){
                        cdeal.add(Obj.Agency__c);
                    }
                }
            }
        }
        //删除
        else{
            if(oldMap != null){
                for(Id Obj : oldMap.keyset()){
                cdeal.add(oldMap.get(Obj).Agency__c);
                }
            }
        }
        
        //统计（经销商，数量）
        if(cdeal.size() > 0){
            //    List<AggregateResult> reout = [select count(Id) ahl, Agency__c from Agency_Hospital_Link__c where Agency__c in :cdeal and Agency_Campaign_Obj__c = true group by Agency__c];
            //    for(AggregateResult acc : reout){
            //     numMap.put((String)acc.get('Agency__c'), (Integer)acc.get('ahl'));
            //    }
    
            //    List<AggregateResult> reoutim = [select count(Id) ahlim, Agency__c from Agency_Hospital_Link__c where Agency__c in :cdeal and Agency_Campaign_Obj__c = true and (Hospital_Category__c ='H0' or Hospital_Category__c ='H1' or Hospital_Category__c ='M0') group by Agency__c];
            //    for(AggregateResult acc1 : reoutim){
            //     numimMap.put((String)acc1.get('Agency__c'), (Integer)acc1.get('ahlim'));
            //    }
            Map<String,Integer> numMap = new Map<String,Integer>();
            Map<String,Integer> numimMap = new Map<String,Integer>();
            List<Agency_Hospital_Link__c> reout = [select Agency__c,Hospital_Category__c from Agency_Hospital_Link__c where Agency__c in :cdeal and Agency_Campaign_Obj__c = true];
            for(Agency_Hospital_Link__c acc : reout){
    
                if(numMap.containskey(acc.Agency__c)){
                    numMap.put(acc.Agency__c, numMap.get(acc.Agency__c)+1);
                }else{
                    numMap.put(acc.Agency__c,1);
                }
    
                if(acc.Hospital_Category__c == 'H0' || acc.Hospital_Category__c == 'H1' || acc.Hospital_Category__c == 'M0'){
                    if(numimMap.containskey(acc.Agency__c)){
                        numimMap.put(acc.Agency__c, numimMap.get(acc.Agency__c)+1);
                    }else{
                        numimMap.put(acc.Agency__c,1);
                    }
                }
            }
            
            //赋值0
            Map<String,Account> acc1 = new Map<String,Account>();
            List<Account> accList = new List<Account>();
            for(String unacc : cdeal){
                Account ac = new Account();
                ac.Id = unacc;
                ac.AgencyHospital_Number__c = numMap.containsKey(unacc)?numMap.get(unacc):0;
                ac.AgencyHospital_Number_Important__c = numimMap.containsKey(unacc)?numimMap.get(unacc):0;
                acc1.put(unacc,ac);            
            }
            for(Account a : acc1.values()){
                accList.add(a);
            }
            if(accList.size()>0){
                update accList;
            }
               
        }
    }
    //SWAG-C5XBY2  精琢科技  lt  2021-08-24  end
}