package cn.ey.biz.module.system.service.user;

import cn.ey.biz.common.pojo.PageResult;
import cn.ey.biz.module.system.api.user.dto.AdminUserRespDTO;
import cn.ey.biz.module.system.api.user.dto.UsersForConditionsReqDTO;
import cn.ey.biz.module.system.api.user.dto.UsersForKeywordsReqDTO;
import cn.ey.biz.module.system.convert.user.UserConvert;
import cn.ey.biz.module.system.dal.dataobject.user.AdminUserES;
import cn.ey.biz.module.system.enums.user.OverseasStaffEnum;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.*;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * bean的实例由ElasticSearchConfiguration动态创建
 */
@Slf4j
public class AdminUserServiceESImpl implements AdminUserSuperService {

    private final  Integer DELETED_NO=0;
    private final  Integer STATUS_YES=0;

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Override
    public PageResult<AdminUserRespDTO> getUserForKeywords(UsersForKeywordsReqDTO userReqDTO) {
        //构建条件
        QueryBuilder queryBuilder = this.buildSearchQueryForKeywords(userReqDTO);
        //获取数据
       return this.searchESPage(queryBuilder,userReqDTO.getPageNo(),userReqDTO.getPageSize());
    }




    private QueryBuilder  buildSearchQueryForKeywords(UsersForKeywordsReqDTO userReqDTO){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //默认非删除
        boolQueryBuilder.must(QueryBuilders.termQuery("deleted",this.DELETED_NO));
        //默认非禁用的
        boolQueryBuilder.must(QueryBuilders.termQuery("status",this.STATUS_YES));
        //如果条件不为空的话，构建查询Query
            //模糊查询
        if(this.checkKeywords(userReqDTO)){
            BoolQueryBuilder boolQueryBuilderChild = QueryBuilders.boolQuery();
            //should(or)
            if(userReqDTO.getIsLikeGPN()){
                boolQueryBuilderChild.should(QueryBuilders.wildcardQuery("gpn","*"+userReqDTO.getKeywords()+"*"));
            }
            if(userReqDTO.getIsLikeEmail()){
                boolQueryBuilderChild.should(QueryBuilders.wildcardQuery("businessEmail","*"+userReqDTO.getKeywords()+"*"));
            }

            if(userReqDTO.getIsLikeUserName()){

                /*
                模糊+分词 结合查询 ,减少容错
                    比如原始数据：Zypwwllxglc Wllbn;
                    输入： ZypwwllxglcT Wllbn ,前缀写错模糊就无法查询出，结合分词根据后缀就可以匹配到。
                    所以需要两者结合使用增加查询体验
                 */

                //模糊
               boolQueryBuilderChild.should(QueryBuilders.wildcardQuery("displayName","*"+userReqDTO.getKeywords()+"*"));
                //分词
                //boolQueryBuilderChild.should(QueryBuilders.matchQuery("displayName",userReqDTO.getKeywords()).operator(Operator.OR));
            }
            boolQueryBuilder.must(boolQueryBuilderChild);
        }

        //must(and)
        //职业级别
        if(CollUtil.isNotEmpty(userReqDTO.getRankCodes())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("rankCode", userReqDTO.getRankCodes()));
        }
        //排除的职业级别
        if(CollUtil.isNotEmpty(userReqDTO.getExclusionRankCodes())){
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("rankCode", userReqDTO.getExclusionRankCodes()));
        }
        //公司实体
        if(CollUtil.isNotEmpty(userReqDTO.getLegalEntitys())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("legalEntity", userReqDTO.getLegalEntitys()));
        }
        //工作国家
        if(StringUtils.isNotBlank(userReqDTO.getCountry())){
            boolQueryBuilder.must(QueryBuilders.termQuery("country", userReqDTO.getCountry()));
        }
        //地理区域
        if(CollUtil.isNotEmpty(userReqDTO.getGeoRegions())){
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("geoRegion", userReqDTO.getGeoRegions()));
        }
        //办公地点
        if(CollUtil.isNotEmpty(userReqDTO.getWorkLocation())){
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("workLocation", userReqDTO.getWorkLocation()));
        }
        //员工状态
        if(CollUtil.isNotEmpty(userReqDTO.getEmployeeStatus())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("employeeStatus", userReqDTO.getEmployeeStatus()));
        }
        //是否包含海外人员
        if(!userReqDTO.getIsOverseasStaff()){
            boolQueryBuilder.must(QueryBuilders.termQuery("isOverseasStaff", OverseasStaffEnum.N.getCode()));
        }

        //如果有条件则返回，无条件则查询所有
        //return boolQueryBuilder.hasClauses() ? boolQueryBuilder:QueryBuilders.matchAllQuery();
        return boolQueryBuilder;

    }
    private boolean checkKeywords(UsersForKeywordsReqDTO userReqDTO){
        if(StringUtils.isNotBlank(userReqDTO.getKeywords()) &&
                (userReqDTO.getIsLikeGPN()||userReqDTO.getIsLikeEmail()||userReqDTO.getIsLikeUserName())){
            return true;
        }
        return false;
    }

    private PageResult<AdminUserRespDTO> searchESPage(QueryBuilder queryBuilder,Integer pageNo,Integer pageSize){

        log.info("boolQueryBuilder:{}",queryBuilder.toString());
        //条件包装
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(queryBuilder);
        //分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of((pageNo-1),pageSize));

        SearchHits<AdminUserES> searchResult = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), AdminUserES.class);
        List<AdminUserES> collect = searchResult.getSearchHits().stream().map(SearchHit::getContent).collect(Collectors.toList());

        return UserConvert.INSTANCE.convertAdminUserESPage( new PageResult(collect, searchResult.getTotalHits()));
    }


    @Override
    public PageResult<AdminUserRespDTO> getUsersForConditions(UsersForConditionsReqDTO userReqDTO) {
        //构建条件
        QueryBuilder queryBuilder = this.buildSearchQueryForConditions(userReqDTO);
        //获取数据
        return this.searchESPage(queryBuilder,userReqDTO.getPageNo(),userReqDTO.getPageSize());
    }

    private QueryBuilder  buildSearchQueryForConditions(UsersForConditionsReqDTO userReqDTO){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //默认非删除
        boolQueryBuilder.must(QueryBuilders.termQuery("deleted",this.DELETED_NO));
        //默认非禁用的
        boolQueryBuilder.must(QueryBuilders.termQuery("status",this.STATUS_YES));
        //如果条件不为空的话，构建查询Query
        //模糊查询
        if(StringUtils.isNotBlank(userReqDTO.getGpn())){
            boolQueryBuilder.must(QueryBuilders.wildcardQuery("gpn","*"+userReqDTO.getGpn()+"*"));
        }

        //是否包含海外人员
        if(!userReqDTO.getIsOverseasStaff()){
            boolQueryBuilder.must(QueryBuilders.termQuery("isOverseasStaff", OverseasStaffEnum.N.getCode()));
        }
        //must(and)
        if(CollUtil.isNotEmpty(userReqDTO.getCitizenship())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("citizenship", userReqDTO.getCitizenship()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getSecondCitizenship())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("secondCitizenship", userReqDTO.getSecondCitizenship()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getEmployeeClass())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("employeeClass", userReqDTO.getEmployeeClass()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getEmployeeStatus())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("employeeStatus", userReqDTO.getEmployeeStatus()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getEmployeeType())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("employeeType", userReqDTO.getEmployeeType()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getBaseLocation())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("baseLocation", userReqDTO.getBaseLocation()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getRankCode())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("rankCode", userReqDTO.getRankCode()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getCountryOfBirth())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("countryOfBirth", userReqDTO.getCountryOfBirth()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getRegionOfBirth())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("regionOfBirth", userReqDTO.getRegionOfBirth()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getRegion())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("region", userReqDTO.getRegion()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getCountry())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("country", userReqDTO.getCountry()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getGeoRegion())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("geoRegion", userReqDTO.getGeoRegion()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getLegalEntity())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("legalEntity", userReqDTO.getLegalEntity()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getBranch())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("branch", userReqDTO.getBranch()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getBuesinessUnit())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("buesinessUnit", userReqDTO.getBuesinessUnit()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getMgmtRegion())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("mgmtRegion", userReqDTO.getMgmtRegion()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getOperatingUnit())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("operatingUnit", userReqDTO.getOperatingUnit()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getMgmtUnit())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("mgmtUnit", userReqDTO.getMgmtUnit()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getSubMgmtUnit())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("subMgmtUnit", userReqDTO.getSubMgmtUnit()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getCodeBlock())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("codeBlock", userReqDTO.getCodeBlock()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getServiceLine())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("serviceLine", userReqDTO.getServiceLine()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getSubServiceLine())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("subServiceLine", userReqDTO.getSubServiceLine()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getWorkLocation())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("workLocation", userReqDTO.getWorkLocation()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getSubLegalEntity())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("subLegalEntity", userReqDTO.getSubLegalEntity()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getStandardHours())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("standardHours", userReqDTO.getStandardHours()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getCompetency())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("competency", userReqDTO.getCompetency()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getSupervisor())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("supervisor", userReqDTO.getSupervisor()));
        }
        if(CollUtil.isNotEmpty(userReqDTO.getGradeId())){
            boolQueryBuilder.must(QueryBuilders.termsQuery("gradeId", userReqDTO.getGradeId()));
        }

        return boolQueryBuilder;

    }

}
