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

import cn.reghao.tnb.search.api.dto.VideoSummary;
import cn.reghao.tnb.search.api.iface.DataSearchService;
import cn.reghao.tnb.search.app.es.DocumentService;
import cn.reghao.tnb.search.app.es.ElasticService;
import cn.reghao.tnb.search.app.es.QueryService;
import cn.reghao.tnb.search.app.lucene.LuceneIndex;
import cn.reghao.tnb.search.app.lucene.LuceneQuery;
import cn.reghao.tnb.search.app.model.po.VideoText;
import cn.reghao.jutil.jdk.db.PageList;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryStringQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2025-03-27 13:55:21
 */
@Slf4j
@DubboService
@Service
public class DataSearchServiceImpl implements DataSearchService {
    private final String index = VideoText.class.getSimpleName().toLowerCase(Locale.ROOT);
    private int ps = 20;
    private final DocumentService documentService;
    private final LuceneIndex luceneIndex;
    private final QueryService<VideoText> esQuery;
    private final LuceneQuery luceneQuery;

    public DataSearchServiceImpl(ElasticService elasticService, LuceneQuery luceneQuery, LuceneIndex luceneIndex) {
        this.esQuery = new QueryService<>(elasticService);
        this.documentService = new DocumentService(elasticService);
        this.luceneQuery = luceneQuery;
        this.luceneIndex = luceneIndex;
    }

    public void addVideoSummary(VideoSummary videoSummary) {
        int type = 1;
        try {
            VideoText videoText = new VideoText(videoSummary);
            if (type == 1) {
                documentService.addVideoText(index, videoText);
            } else{
                luceneIndex.createVideoTextIndex(videoText);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateVideoSummary(VideoSummary videoSummary) {
    }

    @Override
    public void deleteVideoSummary(String videoId) {
    }

    @Override
    public PageList<VideoSummary> searchVideo(String keyword, String nextIdStr, int pn) {
        QueryStringQuery stringQuery = new QueryStringQuery.Builder()
                // 查询的字段
                .fields("title")
                .query(keyword)
                .build();

        boolean vip1 = Boolean.parseBoolean(nextIdStr);
        Query query;
        if (!vip1) {
            query = new Query.Builder()
                    .queryString(stringQuery)
                    .build();
        } else {
            query = new Query.Builder()
                    .bool(BoolQuery.of(b -> b
                            .must(m -> m.term(t -> t.field("vip").value(FieldValue.of(vip1))))
                            .must(m -> m.queryString(stringQuery))))
                    .build();
        }

        Page<VideoText> page = esQuery.queryWithHighlight(index, query, pn, ps, VideoText.class);
        //Page<VideoText> page = esQuery.queryWithHighlight(index, keyword, pn, ps, VideoText.class);
        //Page<VideoText> page1 = luceneQuery.queryWithHighlight(index, keyword, pn, ps);
        List<VideoSummary> list = page.stream().map(videoText -> {
            String videoId = videoText.getVideoId();
            String title = videoText.getTitle();
            String description = videoText.getDescription();
            int scope = videoText.getScope();
            return new VideoSummary(videoId, title, description, scope);
        }).collect(Collectors.toList());
        return PageList.pageList(pn, ps, (int) page.getTotalElements(), list);
    }

    /**
     * 使用 ik 分词器对文本进行分词
     *
     * @param
     * @return
     * @date 2025-03-31 15:35:41
     */
    public List<String> segment(String text) {
        List<String> words = new ArrayList<>();
        try (StringReader reader = new StringReader(text)) {
            IKSegmenter segmenter = new IKSegmenter(reader, true);
            Lexeme lexeme;
            while ((lexeme = segmenter.next()) != null) {
                words.add(lexeme.getLexemeText());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return words;
    }
}
