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

import cn.reghao.tnb.search.api.dto.IndexCount;
import cn.reghao.tnb.search.api.dto.VideoSummary;
import cn.reghao.tnb.search.api.iface.DataSearchService;
import cn.reghao.tnb.search.app.lucene.LuceneDocument;
import cn.reghao.tnb.search.app.lucene.LuceneIndex;
import cn.reghao.tnb.search.app.lucene.LuceneSearch;
import cn.reghao.tnb.search.app.model.po.VideoText;
import cn.reghao.jutil.jdk.web.db.PageList;
import cn.reghao.tnb.search.app.model.vo.VideoQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.lucene.document.Document;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2025-03-27 13:55:21
 */
@Slf4j
@DubboService
@Service
public class DataSearchServiceImpl implements DataSearchService {
    private String indexName = "video_text";
    private int pageSize = 12;
    private LuceneDocument luceneDocument;
    private final LuceneIndex luceneIndex;
    private LuceneSearch luceneSearch;
    private boolean luceneEnabled = true;

    public DataSearchServiceImpl(LuceneDocument luceneDocument, LuceneIndex luceneIndex, LuceneSearch luceneSearch) {
        this.luceneDocument = luceneDocument;
        this.luceneIndex = luceneIndex;
        this.luceneSearch = luceneSearch;
    }

    @Override
    public void addVideoSummary(VideoSummary videoSummary) {
        VideoText videoText = new VideoText(videoSummary);
        if (luceneEnabled) {
            Document document = luceneDocument.getDocumentByVideoText(videoText);
            try {
                luceneIndex.addOrUpdateIndex(indexName, document);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void addVideoSummaryList(List<VideoSummary> list) {
        List<VideoText> videoTextList = list.stream()
                .map(VideoText::new)
                .collect(Collectors.toList());
        if (luceneEnabled) {
            List<Document> documents = videoTextList.stream()
                    .map(videoText -> luceneDocument.getDocumentByVideoText(videoText))
                    .collect(Collectors.toList());
            try {
                luceneIndex.batchAddOrUpdateIndex(indexName, documents);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void updateVideoSummary(VideoSummary videoSummary) {
        VideoText videoText = new VideoText(videoSummary);
        if (luceneEnabled) {
            Document document = luceneDocument.getDocumentByVideoText(videoText);
            try {
                luceneIndex.addOrUpdateIndex(indexName, document);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void deleteVideoSummary(String videoId) {
        if (luceneEnabled) {
            try {
                luceneIndex.deleteIndex(indexName, videoId);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public PageList<VideoSummary> searchVideo(String keyword, List<Integer> scopes, int pageNumber) {
        PageList<VideoSummary> pageList = PageList.empty();
        if (luceneEnabled) {
            VideoQuery videoQuery = new VideoQuery.Builder()
                    .pageSize(pageSize)
                    .pageNumber(pageNumber)
                    .indexName(indexName)
                    .queryFiledNames(List.of("title", "description"))
                    .highlightFiledNames(List.of("title"))
                    .queryString(keyword)
                    .scopes(scopes)
                    .build();

            PageList<VideoText> pageList1 = luceneSearch.queryWithHighlight(videoQuery, VideoText.class);
            List<VideoSummary> list = pageList1.getList().stream().map(this::getVideoSummary).collect(Collectors.toList());
            pageList = PageList.pageList(pageNumber, pageSize, (int) pageList1.getTotalSize(), list);
        }

        return pageList;
    }

    private VideoSummary getVideoSummary(VideoText videoText) {
        String videoId = videoText.getId();
        String title = videoText.getTitle();
        String description = videoText.getDescription();
        int scope = videoText.getScope();
        long publishTime = videoText.getPublishTime();
        return new VideoSummary(videoId, title, description, scope, publishTime);
    }

    @Override
    public IndexCount countIndex(String indexName) {
        try {
            IndexCount indexCount = luceneIndex.countIndex(indexName);
            return indexCount;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}
