/**
 * wangweipeng   20210705
 * opd计划判断所有人和战略科室所有人是否为同一人，如果不同的人，给他加一个共享
 *
 * wangweipeng   2021/08/10
 * 新增共享给科室对应的主担当人
 */
global class OPDStrategyPersonShareBatch implements Database.Batchable<sObject> {
    public String query;
    private String errStr;
    private BatchIF_Log__c iflog;
    private final List<Id> TEST_ID = null;

    global OPDStrategyPersonShareBatch() {
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushNotification';
        iflog.Is_Error__c = 0;
        iflog.Log__c = 'OPDStrategyPersonShareBatch start1\n';
        iflog.ErrorLog__c = '';
        insert iflog;
    }
    global OPDStrategyPersonShareBatch(List<Id> testId) {
        iflog = new BatchIF_Log__c();
        iflog.Type__c = 'PushNotification';
        iflog.Is_Error__c = 0;
        iflog.Log__c = 'OPDStrategyPersonShareBatch start1\n';
        iflog.ErrorLog__c = '';
        insert iflog;

        TEST_ID = testId;
    }
    //add 新建共享数据
    private OPDPlan__Share makeData(String parentId,String userId){
        OPDPlan__Share ras = new OPDPlan__Share();
        ras.RowCause= 'AccountOwnerShare__c';//手动
        ras.ParentId = parentId;//opd id
        ras.UserOrGroupId = userId;//共享给谁
        ras.AccessLevel = 'Edit';//编辑
        return ras;
    }
    //担当人共享数据
    private OPDPlan__Share makeData2(String parentId,String userId){
        OPDPlan__Share ras = new OPDPlan__Share();
        ras.RowCause= 'ProducLeaderShare__c';//手动
        ras.ParentId = parentId;//opd id
        ras.UserOrGroupId = userId;//共享给谁
        ras.AccessLevel = 'Edit';//编辑
        return ras;
    }
    /**
     * 战略科室所有人共享
     * A是所有人 B是战略科室所有人 C共享表共享的人
     *                   什么都不做      0
     * A  = B     C无值  什么都不做      1
     * A  = B  != C有值  删除C           3
     * A != B  =  C有值  什么都不做       2
     * A != B  != C有值  新增共享更新C    5 
     * A != B     C无值  新增共享更新C    4
     *
     *担当人共享
     *
     * 1：等于战略科室所有人或opd计划所有人，什么都不做
     * 2：否则新增共享
     * 
     */
    global Database.QueryLocator start(Database.BatchableContext bc) {
        query = 'select id,Owner.name,Owner.id,Owner.IsActive,Department_owner__c,Status__c, Share_one_id__c , Share_one_type__c,' 
             + ' Account_Laboratory__r.Hospital__r.GI_Product_Leader__c,Account_Laboratory__r.Hospital__r.BF_Product_Leader__c,'
             + ' Account_Laboratory__r.Hospital__r.ET_Product_Leader__c,Account_Laboratory__r.Hospital__r.GS_Product_Leader__c,'
             + ' Account_Laboratory__r.Hospital__r.URO_Produc_Leader__c,'
             + ' Account_Laboratory__r.Hospital__r.GYN_Product_Leader__c,Account_Laboratory__r.Hospital__r.ENT_Product_Leader__c, '
             //+ ' Account_Laboratory__r.Parent.ET_Product_Leader__c'
             + ' Share_Produc_Leader__c,Department_Class__c '
             + ' from OPDPlan__c where Status__c IN (\'完毕未报告\',\'待提交报告\') ';
        if (TEST_ID <> null) {
            query += ' and Id IN: TEST_ID';
        }
        // iflog.Log__c += query+'\n';
        // update iflog;

        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, list<OPDPlan__c> scope) {
        if(scope != null && scope.size() > 0){
            //用于删除旧的共享计划
            List<OPDPlan__Share> delStrategList = new List<OPDPlan__Share>();
            //修改 C  共享里面存的共享人id
            List<OPDPlan__c> updateShareOneId = new List<OPDPlan__c>();
            //删除 修改C 新增 共享
            List<String>  DelShareParentId = new List<String>();
            //增加 B 和C
            List<OPDPlan__Share> InsShare = new List<OPDPlan__Share>();
            //收集要新建的opd id
            List<String> ParentIdList = new List<String>();
            //收集担当人中文名
            List<String> productLeaderNameList = new List<String>();
            List<OPDPlan__c> oPDPlanProductLeaderNameList = new List<OPDPlan__c>();

            //担当人id   DelShareParentId
            List<String> DelShareParentId2 = new List<String>();
            //如果共享了担当人，那么把此担当人id记录到opd计划表，方便我们下次共享时判断
            List<OPDPlan__c> updateShareProducLeader = new List<OPDPlan__c>();
            //新增担当人共享
            List<OPDPlan__Share> InsShareProducLeader = new List<OPDPlan__Share>();

            for(OPDPlan__c occ : scope){
                //共享战略科室所有人
                Integer ShareOneType = Integer.valueOf(occ.Share_one_type__c);
                if(ShareOneType == 3){
                    updateShareOneId.add(new OPDPlan__c(Id=occ.Id,Share_one_id__c=''));
                    DelShareParentId.add(occ.id);
                }
                if(ShareOneType == 4){
                    updateShareOneId.add(new OPDPlan__c(Id=occ.Id,Share_one_id__c=occ.Department_owner__c));
                    if(occ.Department_owner__c != '' && occ.Department_owner__c != null){
                        OPDPlan__Share os = makeData(occ.id,occ.Department_owner__c);
                        InsShare.add(os);
                    }
                }
                if(ShareOneType == 5){
                    updateShareOneId.add(new OPDPlan__c(Id=occ.Id,Share_one_id__c=occ.Department_owner__c));
                    if(occ.Department_owner__c != '' && occ.Department_owner__c != null){
                        OPDPlan__Share os = makeData(occ.id,occ.Department_owner__c);
                        InsShare.add(os);
                    }
                    DelShareParentId.add(occ.id);
                }
               if(occ.Account_Laboratory__c != null){
                    //获取对应的担当人中文名字
                    List<String> getProductLeaderNameList = getProductLeaderName(occ);
                    if(getProductLeaderNameList != null && getProductLeaderNameList.size() > 0){
                        for(String productLeaderName : getProductLeaderNameList){
                            if(productLeaderName != ''){
                                productLeaderNameList.add(productLeaderName);
                                oPDPlanProductLeaderNameList.add(occ);
                            }
                        }
                    }
                    //有可能出现担当人修改成空，那么就需要把原来的共享人删除掉
                    if(getProductLeaderNameList.size() == 0){
                        if(occ.Share_Produc_Leader__c != null){
                            //把此次共享的人员id，存放到opd计划表中
                            updateShareProducLeader.add(new OPDPlan__c(id=occ.id,Share_Produc_Leader__c=''));
                            //删除原来担当人的opd计划共享
                            DelShareParentId2.add(occ.id);
                        }
                    }
               }
            }
            //共享对应的担当人
            if(productLeaderNameList != null && productLeaderNameList.size() > 0){
                //获取担当人的user对象
                List<User> userList = [select id,name,Alias,Alias__c from user where IsActive = true and Alias__c in :productLeaderNameList order by CreatedDate desc];
                if(userList != null && userList.size() > 0){
                    for(OPDPlan__c occ : scope){
                        //获取对应的担当人中文名字
                        List<String> userNameList = getProductLeaderName(occ);
                        //临时变量，用于收集当前opd计划下所有的担当人id
                        String productLeaderId = '';
                        if(userNameList != null && userNameList.size() > 0){
                            for(String usrName : userNameList){
                                for(User u : userList){
                                    //首先找到对应的担当人
                                    //由于可能出现同名的担当人，所以我们需要首先收集所有的担当人，再后期处理
                                    if(usrName == u.Alias__c){
                                        if(productLeaderId == ''){
                                            productLeaderId = u.id;
                                        }else{
                                            productLeaderId += ','+u.id;
                                        }
                                    }
                                }
                            }
                        }
                        //处理担当人的数据
                        if(productLeaderId != ''){
                            //判断此担当人是否已经共享
                            if(!productLeaderId.equals(occ.Share_Produc_Leader__c)){
                                //判断担当人是否不等于  战略科室所有人或opd计划所有人，如果和其中一个相等，那么不需要加再给此人加共享了
                                if(!productLeaderId.equals(occ.Department_owner__c) && !productLeaderId.equals(occ.Owner.Id)){
                                    //由于可能出现同名的担当人，那么我们需要把这些同名的人都共享
                                    List<String> userIdList = productLeaderId.split(',');
                                    for(String uId : userIdList){
                                        if(uId != '' && uId != null){
                                            InsShareProducLeader.add(makeData2(occ.id,uId));
                                        }
                                    }
                                    //把此次共享的人员id，存放到opd计划表中
                                    updateShareProducLeader.add(new OPDPlan__c(id=occ.id,Share_Produc_Leader__c=productLeaderId));
                                    //删除原来担当人的opd计划共享
                                    DelShareParentId2.add(occ.id);
                                }else{
                                    //判断词条opd计划的数据是否有担当人共享数据
                                    if(String.isNotBlank(occ.Share_Produc_Leader__c)){
                                        //修改opd计划的担当人共享字段，设置为空
                                        updateShareProducLeader.add(new OPDPlan__c(id=occ.id,Share_Produc_Leader__c=''));
                                        //删除原来担当人的opd计划共享
                                        DelShareParentId2.add(occ.id);

                                    }
                                }
                            }
                        }else{//如果没有收集到担当人的id，那么证明此担当人不存在系统中或没启用
                            //判断词条opd计划的数据是否有担当人共享数据
                            if(String.isNotBlank(occ.Share_Produc_Leader__c)){
                                //修改opd计划的担当人共享字段，设置为空
                                updateShareProducLeader.add(new OPDPlan__c(id=occ.id,Share_Produc_Leader__c=''));
                                //删除原来担当人的opd计划共享
                                DelShareParentId2.add(occ.id);

                            }
                        }
                    }
                }else{//如果没有在user表中查找到人员，那么有可能是此用户在系统中不存在或没有启用，所有要把以前的共享担当人值置空
                    for(OPDPlan__c productLeaderNameId : oPDPlanProductLeaderNameList){
                        if(String.isNotBlank(productLeaderNameId.Share_Produc_Leader__c)){
                            //修改opd计划的担当人共享字段，设置为空
                            updateShareProducLeader.add(new OPDPlan__c(id=productLeaderNameId.id,Share_Produc_Leader__c=''));
                            //删除原来担当人的opd计划共享
                            DelShareParentId2.add(productLeaderNameId.id);

                        }
                    }
                }
            }
            Savepoint sp = Database.setSavepoint();
            try{
                //opd计划 战略科室所有人共享
                //删除原来的opd共享
                if(DelShareParentId != null && DelShareParentId.size() > 0){
                    delStrategList = [SELECT Id,ParentId,UserOrGroupId FROM OPDPlan__Share WHERE RowCause ='AccountOwnerShare__c' AND ParentId in :DelShareParentId];
                    if(delStrategList != null && delStrategList.size() > 0){
                        delete delStrategList;
                    }
                }
                if(InsShare != null && InsShare.size() > 0){
                    //新建新的共享
                    insert InsShare;
                }
                if(updateShareOneId != null && updateShareOneId.size() > 0){
                    //更新修理表中 共享表共享人id
                    update updateShareOneId;
                }
                //以下是共享担当人
                if(DelShareParentId2 != null && DelShareParentId2.size() > 0){
                    List<OPDPlan__Share> delProducLeaderList = [SELECT Id,ParentId,UserOrGroupId FROM OPDPlan__Share WHERE RowCause ='ProducLeaderShare__c' AND ParentId in :DelShareParentId2];
                    if(delProducLeaderList != null && delProducLeaderList.size() > 0){
                        delete delProducLeaderList;
                    }
                }
                if(InsShareProducLeader != null && InsShareProducLeader.size() > 0){
                    insert InsShareProducLeader;
                }
                if(updateShareProducLeader != null && updateShareProducLeader.size() > 0){
                    update updateShareProducLeader;
                }
            }catch(exception e){
                System.debug('*****************'+e.getMessage());
                errStr = e.getMessage()+'\n';
                errStr += e.getLineNumber()+'\n';
                Database.rollback(sp);
            }
        }
    }

    //获取对应的担当人中文名
    public List<String> getProductLeaderName(OPDPlan__c opc){
        List<String> productLeaderNameList = new List<String>();//担当中文名
        if(opc != null){
            String productLeader = '';
            String departmentType = opc.Department_Class__c;//科室分类
            if(departmentType != ''){
                if('消化科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.GI_Product_Leader__c;}
                if('呼吸科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.BF_Product_Leader__c;}
                if('普外科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.GS_Product_Leader__c;}
                if('泌尿科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.URO_Produc_Leader__c;}
                if('妇科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.GYN_Product_Leader__c;}
                if('耳鼻喉科'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.ENT_Product_Leader__c;}
                if('ET'.equals(departmentType)){productLeader = opc.Account_Laboratory__r.Hospital__r.ET_Product_Leader__c;}
                //由于担当人可能是定义个人所以需要循环一下
                if(productLeader != '' && productLeader != null){
                    if(productLeader.indexOf('，') != -1){
                        productLeader = productLeader.replace('，',',');
                    }
                    if(productLeader.indexOf(' ') != -1){
                        productLeader = productLeader.replace(' ','');
                    }
                    for (String usrName1 : productLeader.split(',')) {
                        if(!(''.equals(usrName1))){
                            productLeaderNameList.add(usrName1);
                        }
                    }
                }
            }
        }
        return productLeaderNameList;
    }

    global void finish(Database.BatchableContext BC) {
        String tmp = '';
        if (String.isNotBlank(errStr)) {
            tmp = errStr;
        }
        iflog.Log__c += query+'\n';
        iflog.Log__c += 'OPDStrategyPersonShareBatch finish()\n';
        iflog.Log__c += '\nOPDStrategyPersonShareBatch end';

        tmp += iflog.ErrorLog__c;
        if (tmp.length() > 60000) {
          tmp = tmp.substring(0, 60000);
          tmp += ' ...have more lines...';
          iflog.ErrorLog__c = tmp;
        }
        String tmp2 = iflog.Log__c;
        if (tmp2.length() > 60000) {
          tmp2 = tmp2.substring(0, 60000);
          tmp2 += ' ...have more lines...';
          iflog.Log__c = tmp2;
        }
        if (System.Label.Log_IO_Flag == 'Keep') {
          update iflog;
        } else if (System.Label.Log_IO_Flag == 'Auto') {
          if (iflog.Is_Error__c > 0) {
            update iflog;
          }
        }
    }
}