package com.search.supersearch;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.json.JSONUtil;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.core.search.HitsMetadata;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.search.supersearch.common.R;
import com.search.supersearch.domain.DwdNocFilesEs;
import com.search.supersearch.domain.IamDataCategory;
import com.search.supersearch.domain.IamSearchCategoryidIndexname;
import com.search.supersearch.model.dto.IamCategoryIndexBean;
import com.search.supersearch.model.dto.SearchDTO;
import com.search.supersearch.model.vo.DocsIndexVO;
import com.search.supersearch.service.DocsService;
import com.search.supersearch.service.pgsql.DwdNocFilesEsService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 测试 elasticSearch client 索引相关的操作
 *
 * @author WT
 * @date 2021/12/28 16:27:45
 */
@Slf4j
@SpringBootTest
@ActiveProfiles("wr") //这里
public class TmpTest {
    @Resource
    private DwdNocFilesEsService dwdNocFilesEsService;
    @Resource
    private DocsService docsService;
    @Test
    @SneakyThrows
    public void run3() {
        FileReader fileReader = new FileReader("tmp.txt");
        String result = fileReader.readString();
        System.out.println(result);
        String authorization = result;
    }
    @Test
    @SneakyThrows
    public void run2() {
        Page<DwdNocFilesEs> page = dwdNocFilesEsService.lambdaQuery()
                .eq(DwdNocFilesEs::getTrans2es, 0)
                .page(new Page<>(1, 10));

        System.out.println(JSONUtil.toJsonStr(page));
        System.out.println("==========");
        DwdNocFilesEs dwdNocFilesEs = page.getRecords().get(0);
        Map<String, Object> dwdFieldMap = BeanUtil.beanToMap(dwdNocFilesEs);
        System.out.println(JSONUtil.toJsonStr(dwdFieldMap));

    }

    @Test
    @SneakyThrows
    public void run() {
        SearchDTO dto = new SearchDTO();
        dto.setHideType(Lists.newArrayList());
        dto.setKeyword("职业病危害严重的用人单位，应当委托具有相应资格的职业卫生技术服务机构");
        dto.setMatch(2);
        dto.setSort(1);
//        dto.setSearchAfter(Lists.newArrayList("1703583956897","1.0594347"));


        log.info("com.search.supersearch.controller.docs.DocsV3Controller.searchAllV2 开始执行={}", System.currentTimeMillis());

        String keyword = dto.getKeyword();

        if (dto.getSize() == null) {
            dto.setSize(3);
        }
        ArrayList<DocsIndexVO> vos = Lists.newArrayList();
        log.info("com.search.supersearch.controller.docs.DocsV3Controller.searchAllV2 开始请求权限计算={}", System.currentTimeMillis());
        Object invokePermission = invokePermission("", "authorization");
        log.info("com.search.supersearch.controller.docs.DocsV3Controller.searchAllV2 请求权限计算结束={}", System.currentTimeMillis());
        if (invokePermission instanceof String) {
            R fail = R.fail("请求权限接口失败!");
            fail.setExt((String) invokePermission);

            log.info("请求权限接口失败!");
        }
        List<IamCategoryIndexBean> category = (List<IamCategoryIndexBean>) invokePermission;

        if (category.size() < 1) {
            log.info("该用户没有任何权限!");
        }
        List<String> hideType = dto.getHideType();

        for (IamCategoryIndexBean iamDataCategory : category) {

            IamDataCategory dataCategoryBean = iamDataCategory.getDataCategoryBean();
            if (hideType != null && hideType.stream().anyMatch(v -> v.equalsIgnoreCase(dataCategoryBean.getCategoryId()))) {
                continue;
            }
            List<String> index = iamDataCategory.getIndexBeanList().stream().map(IamSearchCategoryidIndexname::getIndexName).collect(Collectors.toList());
            Map<String, List<String>> map = iamDataCategory.getIndexBeanList().stream().collect(Collectors.toMap(IamSearchCategoryidIndexname::getIndexName, i -> Optional.ofNullable(i.getOrgCodes()).orElse(Lists.newArrayList())));

            categoryAllIndex(index, map, iamDataCategory);
            SearchResponse<Map> search = docsService.searchHitv2(keyword, dto.getMatch(),0, index, dto.getSize(), dto.getSearchAfter(), map);
            if (search == null) {
                continue;
            }
            HitsMetadata<Map> hits = search.hits();
            if (hits.total() == null || hits.total().value() == 0) {
                continue;
            }
            DocsIndexVO vo = getDocsIndexVO(hits, dataCategoryBean.getCategoryId(), dataCategoryBean.getCategoryName());
            vos.add(vo);
        }
        log.info("com.search.supersearch.controller.docs.DocsV3Controller.searchAllV2 执行结束={}", System.currentTimeMillis());

        log.info("返回={}", vos);
    }

    private Object invokePermission(String id, String token) {
        if (StringUtils.isEmpty(id)) {
            id = "";
        }
        log.info("数据权限请求参数={}", id);
        FileReader fileReader = new FileReader("tmp.txt");
        String result = fileReader.readString();
        String authorization = result;
        log.info("数据权限请求结果={}", authorization);
        List<IamCategoryIndexBean> iamCategoryIndexBeans = null;
        try {
            iamCategoryIndexBeans = JSONUtil.toList(authorization, IamCategoryIndexBean.class);
        } catch (Exception e) {

            log.error("数据权限请求结果={}", authorization);
            return authorization;
        }

        return iamCategoryIndexBeans;
    }

    private DocsIndexVO getDocsIndexVO(HitsMetadata<Map> hits, String type, String name) {
        DocsIndexVO vo = new DocsIndexVO();
        ArrayList<Object> list = Lists.newArrayList();

        vo.setTotal(hits.total().value());
        vo.setData(list);
        vo.setType(type);
        vo.setName(name);
        for (Hit<Map> docsIndexHit : hits.hits()) {
            DocsIndexVO.DocsIndexInfo info = new DocsIndexVO.DocsIndexInfo();
            Map source = docsIndexHit.source();
            assert source != null;
            String es_content = (String) source.get("es_data_content");
            if (es_content.length() > 300) {
                source.put("es_data_content", es_content.substring(0, 200));
            }
            String path = (String) source.get("es_file_path");
            if (StringUtils.isNotBlank(path)) {
                source.put("es_file_path", path.substring(path.lastIndexOf("/") + 1));

            }
            info.setSource(source);
            info.setHighlight(docsIndexHit.highlight());
            info.setSearchAfter(docsIndexHit.sort().stream().map(v -> v._get() + "").collect(Collectors.toList()));
            list.add(info);
        }
        return vo;
    }

    private void categoryAllIndex(List<String> index, Map<String, List<String>> map, IamCategoryIndexBean iamCategoryIndexBean) {
        List<IamCategoryIndexBean> children = iamCategoryIndexBean.getChildren();
        if (children != null && children.size() > 0) {
            for (IamCategoryIndexBean child : children) {
                List<String> collect = child.getIndexBeanList().stream().map(IamSearchCategoryidIndexname::getIndexName).collect(Collectors.toList());
                Map<String, List<String>> map2 = child.getIndexBeanList().stream().collect(Collectors.toMap(IamSearchCategoryidIndexname::getIndexName, i -> Optional.ofNullable(i.getOrgCodes()).orElse(Lists.newArrayList())));
                map.putAll(map2);
                index.addAll(collect);
                categoryAllIndex(index, map, child);
            }
        }
    }
}
