package com.slodon.b2b2c.investment.model;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.slodon.b2b2c.core.util.HttpClientUtil;
import com.slodon.b2b2c.investment.config.DifyConfig;
import com.slodon.b2b2c.investment.constant.InvestmentConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;
import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sunshihao
 * @version 1.0
 * @description: dify api调用
 * @date 2025/8/14 11:56
 */
@Component
@Slf4j
public class DifyModel {


    @Resource
    private DifyConfig difyConfig;

    /***
     * @description: 获取请求头
     * @author sunshihao
     * @date: 2025/8/14 14:06
     */
    private HashMap<String,String> getCredential(){
        String apiKey = difyConfig.getApiKey();
        HashMap<String, String> headers = new HashMap<>();
        headers.put(InvestmentConst.AUTHORIZATION, InvestmentConst.BEARER +apiKey);
        headers.put(InvestmentConst.CONTENT_TYPE, InvestmentConst.APPLICATION_JSON);
        return headers;
    }

    /***
     * @description:  通过文本创建文档
     * @param dataSetId 知识库id
     * @param name 文件名
     * @param text 文件内容
     * @author sunshihao
     * @date: 2025/8/14 14:06
     */
    public void createByText(String dataSetId, String name, String text) throws Exception {
        HashMap<String, String> header = getCredential();
        JSONObject payloadItem = getTextParam(name, text);
        String url = difyConfig.getDifyRoute()+dataSetId+ InvestmentConst.CREATE_BY_TEXT;
        String post = HttpClientUtil.httpPost(url, payloadItem.toString(),header);
        JSONObject postObject = JSONUtil.parseObj(post);
        String docId = postObject.getByPath(InvestmentConst.DOCUMENT_ID, String.class);
        if(docId==null){
            throw new Exception("根据文本创建文档失败");
        }
    }


    /***
     * @description: 通过文本更新文档
     * @param dataSetId 知识库id
     * @param documentId 原文档id
     * @param name 文件名
     * @param text 文件内容
     * @return: void
     * @author sunshihao
     * @date: 2025/8/14 14:06
     */
    public void updateByText(String dataSetId, String documentId,String name, String text) throws Exception {
        HashMap<String, String> header = getCredential();
        JSONObject payloadItem = getTextParam(name, text);
        String url = difyConfig.getDifyRoute()+dataSetId+ InvestmentConst.DOCUMENTS +documentId+ InvestmentConst.UPDATE_BY_TEXT;
        String post = HttpClientUtil.httpPost(url, payloadItem.toString(),header);
        JSONObject postObject = JSONUtil.parseObj(post);
        String docId = postObject.getByPath(InvestmentConst.DOCUMENT_ID, String.class);
        if(docId==null){
            throw new Exception("根据文本修改文档失败");
        }
    }

    /***
     * @description: 获取文本参数
     * @param name 文件名
     * @param text 文件内容
     * @return: cn.hutool.json.JSONObject
     * @author sunshihao
     * @date: 2025/8/14 14:07
     */
    private JSONObject getTextParam(String name, String text) {
        JSONObject payloadItem = new JSONObject();
        payloadItem.set(InvestmentConst.NAME, name);
        payloadItem.set(InvestmentConst.TEXT, text);
        payloadItem.set(InvestmentConst.INDEXING_TECHNIQUE, InvestmentConst.HIGH_QUALITY);
        JSONObject mode = new JSONObject();
        mode.set(InvestmentConst.MODE, InvestmentConst.AUTOMATIC);
        payloadItem.set(InvestmentConst.PROCESS_RULE, mode);
        return payloadItem;
    }


    /***
     * @description:通过文件创建文档
     * @param dataSetId 知识库id
     * @param file 文件
     * @return: void
     * @author sunshihao
     * @date: 2025/8/14 14:09
     */
    public void createByFile(String dataSetId,File file) throws Exception {
        HashMap<String, String> header = getCredential();
        JSONObject payloadItem = getFileParam();
        String url = difyConfig.getDifyRoute()+dataSetId+ InvestmentConst.CREATE_BY_FILE;
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put(InvestmentConst.FILE, file);
        paramMap.put(InvestmentConst.DATA, payloadItem);
        String post = HttpClientUtil.httpPost(url, paramMap,header);
        JSONObject postObject = JSONUtil.parseObj(post);
        String docId = postObject.getByPath(InvestmentConst.DOCUMENT_ID, String.class);
        if(docId==null){
            throw new Exception("通过文件创建文档失败");
        }
    }


    /***
     * @description: 通过文件修改文档
     * @param:
     * @param dataSetId 知识库id
     * @param documentId 原文件id
     * @param name 修改后的文件名
     * @param file 文件
     * @return: void
     * @author sunshihao
     * @date: 2025/8/14 14:10
     */
    public void updateByFile(String dataSetId, String documentId, String name, File file) throws Exception {
        HashMap<String, String> header = getCredential();
        JSONObject payloadItem = getFileParam();
        if(!StringUtils.isEmpty(name)){
            payloadItem.set(InvestmentConst.NAME,name);
        }
        String url = difyConfig.getDifyRoute()+dataSetId+InvestmentConst.DOCUMENTS+documentId+ InvestmentConst.UPDATE_BY_FILE;
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put(InvestmentConst.FILE, file);
        paramMap.put(InvestmentConst.DATA, payloadItem);
        String post = HttpClientUtil.httpPost(url, paramMap,header);
        JSONObject postObject = JSONUtil.parseObj(post);
        String docId = postObject.getByPath(InvestmentConst.DOCUMENT_ID, String.class);
        if(docId==null){
            throw new Exception("通过文件修改文档失败");
        }
    }

    /***
     * @description:设置文件接口参数
     * @return: cn.hutool.json.JSONObject
     * @author sunshihao
     * @date: 2025/8/14 14:11
     */
    private static JSONObject getFileParam() {
        JSONObject payloadItem = new JSONObject();
        payloadItem.set(InvestmentConst.INDEXING_TECHNIQUE, InvestmentConst.HIGH_QUALITY);
        JSONObject rules = new JSONObject();
        JSONArray preProcessingRules = new JSONArray();
        JSONObject space = new JSONObject();
        space.set(InvestmentConst.ID, InvestmentConst.REMOVE_EXTRA_SPACES);
        space.set(InvestmentConst.ENABLED, false);
        JSONObject emails = new JSONObject();
        emails.set(InvestmentConst.ID, InvestmentConst.REMOVE_URLS_EMAILS);
        emails.set(InvestmentConst.ENABLED, false);
        preProcessingRules.add(space);
        preProcessingRules.add(emails);
        JSONObject segmentation = new JSONObject();
        segmentation.set(InvestmentConst.SEPARATOR, InvestmentConst.SEPARATOR_VALUE);
        segmentation.set(InvestmentConst.MAX_TOKENS, InvestmentConst.NUM_ONE_THOUSAND);
        rules.set(InvestmentConst.PRE_PROCESSING_RULES, preProcessingRules);
        rules.set(InvestmentConst.SEGMENTATION, segmentation);
        JSONObject processRule = new JSONObject();
        processRule.set(InvestmentConst.RULES, rules);
        processRule.set(InvestmentConst.MODE, InvestmentConst.CUSTOM);
        payloadItem.set(InvestmentConst.PROCESS_RULE, processRule);
        return payloadItem;
    }

    /***
     * @description:删除文档
     * @param dataSetId 知识库id
     * @param documentId  原文件id
     * @return: void
     * @author sunshihao
     * @date: 2025/8/14 14:11
     */
    public void deleteDoc(String dataSetId, String documentId) throws Exception {
        HashMap<String, String> header = getCredential();
        String url = difyConfig.getDifyRoute()+dataSetId+InvestmentConst.DOCUMENTS+documentId;
        String post = HttpClientUtil.httpDelete(url,header);
        if(!InvestmentConst.DELETE_SUCCESS.equals(post)){
            throw new Exception("删除文档失败");
        }
    }

    /***
     * @description: 查询知识库列表
     * @param keyword 关键词
     * @param tagIds 标签数组
     * @param page 页码
     * @author sunshihao
     * @date: 2025/8/18 11:35
     */
    public List<String> datasets(String keyword, String[] tagIds, Integer page, List<String> list) throws Exception {
        if (list == null) {
            list = new ArrayList<>();
        }
        int currentPage = (page == null || page <= InvestmentConst.NUM_ZERO) ? InvestmentConst.NUM_ONE : page;
        int limit = InvestmentConst.NUM_ONE_HUNDRED;
        HashMap<String, String> header = getCredential();
        String baseUrl = difyConfig.getDifyRoute();
        while (true) {
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
                    .queryParam(InvestmentConst.PAGE, currentPage)
                    .queryParam(InvestmentConst.LIMIT, limit);

            if (!StringUtils.isEmpty(keyword)) {
                builder.queryParam(InvestmentConst.KEYWORD, keyword);
            }
            if (tagIds != null && tagIds.length > 0) {
                String tagIdsStr = String.join(",", tagIds);
                builder.queryParam("tag_ids", tagIdsStr);
            }
            String url = builder.toUriString();
            String response = HttpClientUtil.httpGet(url, header);
            if (response == null) {
                throw new Exception("HTTP请求返回空响应");
            }
            JSONObject postObject = JSONUtil.parseObj(response);
            JSONArray dataArray = postObject.getByPath(InvestmentConst.DATA, JSONArray.class);
            if (dataArray == null) {
                throw new Exception("查询知识库失败：data字段为空");
            }
            for (Object o : dataArray) {
                JSONObject obj = (JSONObject) o;
                String id = obj.getByPath(InvestmentConst.ID, String.class);
                if (id != null) {
                    list.add(id);
                }
            }
            Integer total = postObject.getByPath(InvestmentConst.TOTAL, Integer.class);
            if (total == null) {
                throw new Exception("响应中缺少 total 字段");
            }
            if (list.size() >= total) {
                break;
            }
            currentPage++;
        }
        return list;
    }

    /*** 
     * @description: 查询知识库当中的文章列表
     * @param datasetId 知识库id
     * @param name 文章名称
     * @return: java.lang.String 文章id
     * @author sunshihao
     * @date: 2025/8/18 13:44
     */ 
    public String documents(String datasetId,String name) throws Exception {
        HashMap<String, String> header = getCredential();
        String baseUrl = difyConfig.getDifyRoute()+datasetId+"/documents";
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
                .queryParam(InvestmentConst.PAGE, InvestmentConst.NUM_ONE)
                .queryParam(InvestmentConst.LIMIT, InvestmentConst.NUM_ONE_HUNDRED);
        if (!StringUtils.isEmpty(name)) {
            builder.queryParam(InvestmentConst.KEYWORD, name);
        }
        String url = builder.toUriString();
        String response = HttpClientUtil.httpGet(url, header);
        if (response == null) {
            throw new Exception("HTTP请求返回空响应");
        }
        JSONObject postObject = JSONUtil.parseObj(response);
        JSONArray dataArray = postObject.getByPath(InvestmentConst.DATA, JSONArray.class);
        if (dataArray == null) {
            throw new Exception("查询文章失败：data字段为空");
        }
        for (Object o : dataArray) {
            JSONObject obj = (JSONObject) o;
            return obj.getByPath(InvestmentConst.ID, String.class);
        }
        return null;
    }
}
