package com.search.supersearch.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.search.supersearch.domain.DwdNocFilesEs;
import com.search.supersearch.model.pojo.DocsIndex;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.tika.Tika;
import org.apache.tika.metadata.Metadata;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

/**
 * @author 喜欢番茄火锅
 * @date 2023/10/9 14:46
 */
@Service
@Slf4j
public class EsService {
    @Resource
    private ElasticsearchClient elasticsearchClient;
    @Resource
    private TikaService tikaService;
    @Resource
    private OcrService ocrService;

    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    //封装同名称属性复制，但是空属性不复制过去
    public static void copyPropertiesIgnoreNull(Object src, Object target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }

    public DocsIndex getByFileId(String fileId) throws IOException {
//        List<IamSearchCategoryidIndexname> list = iamSearchCategoryidIndexnameService.list();
//        List<String> collect = list.stream().map(v -> v.getIndexName()).collect(Collectors.toList());

        SearchResponse<DocsIndex> search = elasticsearchClient.search(s -> {
                    SearchRequest.Builder index = s.index("");
                    index.query(q -> q.term(v -> v.field("es_fileId").value(fileId)));
                    return index;
                }
                ,
                DocsIndex.class);
        List<Hit<DocsIndex>> hits = search.hits().hits();
        for (Hit<DocsIndex> hit : hits) {
            return hit.source();
        }
        return null;
    }

    public void saveFile(URL url, String index, DwdNocFilesEs dwdField) throws Exception {
        File f = new File("./tmp/tmp_" + IdUtil.fastSimpleUUID());
        FileUtils.copyURLToFile(url, f);
        saveFile(f, index, dwdField);
        if (f.exists()) {
            f.delete();
        }
    }

    public Integer saveFile(File file, String index, DwdNocFilesEs dwdField) throws Exception {
        String content = null;
        String detect = null;
        Metadata metadata = new Metadata();
        try {
            Tika tika = new Tika();
            tika.setMaxStringLength(-1);
            detect = tika.detect(file);
            content = tikaService.parser(file, metadata);
//        if (detect.contains("image") || detect.contains("pdf")) {
            if (detect.contains("image")) {
//                content = ocrService.ocr(file, detect.split("/")[1]);
            }
            DocsIndex docsIndex = getDocsIndex(index, dwdField, content);

            DocsIndex.MetaInfo metaInfo = new DocsIndex.MetaInfo();
            metaInfo.setMetaAuthor(metadata.get("meta:last-author"));
            metaInfo.setMetaModifier(metadata.get("dcterms:modified"));
            metaInfo.setMetaCreated(metadata.get("dcterms:created"));
            metaInfo.setMetaContentType(tika.detect(file));
            metaInfo.setMetaFilesize(file.length() + "");
            metaInfo.setMetaFilename(file.getName());
            metaInfo.setMetaFileUrl(file.getPath());

            Map<String, Object> metaInfoMap = BeanUtil.beanToMap(metaInfo);
            Map<String, Object> dwdFieldMap = BeanUtil.beanToMap(dwdField);

            metaInfoMap.putAll(dwdFieldMap);
            log.info("===== 狗崽的 data =====");
            log.info(JSONUtil.toJsonStr(metaInfoMap));
            docsIndex.setData(metaInfoMap);
            saveFile(index, docsIndex);
        } catch (Exception e) {
            log.info("异常文件={},异常信息={}", file.getName(), e.getMessage());
//            e.printStackTrace();
            return 5;
        }
        return 1;
    }

    private DocsIndex getDocsIndex(String index, DwdNocFilesEs dwdField, String content) throws Exception {
        DocsIndex docsIndex = new DocsIndex();
        docsIndex.setEs_data_content(content);
        docsIndex.setEs_data_simple_content(content);
        if (StringUtils.isNotEmpty(content) && content.length() > 300) {
            docsIndex.setEs_data_simple_content(content.substring(0, 200));
        }

        docsIndex.setEs_data_source(dwdField.getSystemName());
        docsIndex.setEs_data_type("0");
        docsIndex.setEs_data_title(dwdField.getFileName());
        docsIndex.setEs_data_time(dwdField.getFileImportTime()+"");
        docsIndex.setEs_order_time(dwdField.getFileImportTime());

        if (StringUtils.isEmpty(dwdField.getUuid())) {
            docsIndex.setEs_fileId(IdUtil.fastSimpleUUID());
        } else {
            docsIndex.setEs_fileId(dwdField.getUuid());
        }
        docsIndex.setEs_index_creat_date(new Date());
//        docsIndex.setEs_file_path(dwdField.getOssFileFullPath().substring(dwdField.getOssFileFullPath().lastIndexOf("/") + 1));
        docsIndex.setEs_file_path(dwdField.getOssFileFullPath());
        docsIndex.setEs_index_name(index);
        if (StringUtils.isEmpty(dwdField.getOrgId())) {
            throw new Exception("DwdNocFilesEs数据不合法!orgid 为空!");
        }
        docsIndex.setEs_ord_id(dwdField.getOrgId());
        return docsIndex;
    }

    public void saveFile(String index, DocsIndex docsIndex) throws IOException {
        elasticsearchClient.index(i -> i.index(index).document(docsIndex));
    }


}
