package cn.reghao.tnb.search.app.hibernate;

import cn.reghao.tnb.search.app.db.repository.WenshuDocRepository;
import cn.reghao.tnb.search.app.model.po.Wenshu;
import cn.reghao.tnb.search.app.model.po.WenshuDoc;
import cn.reghao.tnb.search.app.model.vo.WenshuDocProjection;
import cn.reghao.tnb.search.app.model.vo.WenshuResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.hibernate.search.engine.search.query.SearchResult;
import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.session.SearchSession;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;

import javax.persistence.EntityManagerFactory;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2023-04-15 03:47:50
 */
@Slf4j
@Service
public class HibernateQuery {
    private final SearchSession searchSession;
    private final Analyzer analyzer;
    private final SimpleHTMLFormatter formatter;
    private WenshuDocRepository wenshuDocRepository;

    public HibernateQuery(EntityManagerFactory entityManagerFactory, WenshuDocRepository wenshuDocRepository) {
        this.searchSession = Search.session(entityManagerFactory.createEntityManager());
        this.analyzer = new IKAnalyzer();
        this.formatter = new SimpleHTMLFormatter("<span style='color:red;'>", "</span>");
        this.wenshuDocRepository = wenshuDocRepository;
    }

    public Page<WenshuResult> search(String keyword, Pageable pageable) {
        int pn = pageable.getPageNumber();
        int ps = pageable.getPageSize();
        SearchResult<WenshuDocProjection> highlightResult = searchSession.search(WenshuDoc.class)
                .select(f -> f.composite()
                        .from(f.field("wenshuId", String.class),
                                f.highlight("caseName"))
                        .as(WenshuDocProjection::new))
                .where(f -> f.bool(b -> {
                    b.must(f.matchAll())
                            .should(f.match().field("caseName").matching(keyword).boost(3));
                }))
                .highlighter(f -> f.plain().tag("<span style='color:red;'>", "</span>"))
                .fetch(pn*ps, ps);

        long totalHitCount = highlightResult.total().hitCount();
        List<WenshuDocProjection> list1 = highlightResult.hits();
        List<WenshuResult> wenshuResultList = list1.stream().map(wenshuDocProjection -> {
            String wenshuId = wenshuDocProjection.getWenshuId();
            WenshuDoc wenshuDoc = wenshuDocRepository.findByWenshuId(Long.parseLong(wenshuId));
            Wenshu wenshu = new Wenshu(wenshuDoc);
            WenshuResult wenshuResult = new WenshuResult(wenshu);

            List<String> highlightCaseName = wenshuDocProjection.getHighlightCaseName();
            if (!highlightCaseName.isEmpty()) {
                String caseName = highlightCaseName.get(0);
                wenshuResult.setCaseName(caseName);
            }
            return wenshuResult;
        }).collect(Collectors.toList());
        return new PageImpl<>(wenshuResultList, pageable, totalHitCount);
    }
}
