package com.infoepoch.pms.dispatchassistant.domain.langchain.chat.searchEngineChat;



import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.domain.langchain.chat.History;
import io.micrometer.core.instrument.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SearchEngineChatRequest {

    /**
     * 添加历史记录
     *
     * @param role
     * @param content
     */
    public void addHistory(String role, String content) {
        if (StringUtils.isBlank(role))
            throw new ValidationException("角色不可为空");
        if (StringUtils.isBlank(content))
            throw new ValidationException("内容不可为空");
        if (this.history == null)
            this.history = new ArrayList<>();
        History history = new History(
                role,
                content
        );
        this.history.add(history);
    }

    /**
     * 校验
     */
    public void verify() {
        // 查询语句不可为空
        if (StringUtils.isBlank(this.query))
            throw new ValidationException("查询语句不可为空");
        if (StringUtils.isBlank(this.searchEngineName))
            throw new ValidationException("搜索引擎名称不可为空");
        if (this.topK == null)
            throw new ValidationException("topK不可为空");
        // 历史记录如果为null则置为空列表
        if (this.history == null) {
            this.history = new ArrayList<>();
        }
        if (this.stream == null)
            this.stream = false;
        if (this.modelName == null || this.modelName.isEmpty())
            throw new ValidationException("模型名称不可为空");
        if (this.temperature == null)
            throw new ValidationException("temperature不可为空");
        if (this.maxTokens == null)
            throw new ValidationException("最大字数不可为空");
        if (this.promptName == null || this.promptName.isEmpty())
            throw new ValidationException("提示词名称不可为空");
        if(this.splitResult == null)
            this.splitResult = false;
    }

    /**
     * 转换为请求MAP
     *
     * @return
     */
    public Map<String, Object> toMap() {
        this.verify();
        Map<String, Object> map = new HashMap<>();
        map.put("query", this.query);
        map.put("search_engine_name", this.searchEngineName);
        map.put("top_k", this.topK);
        map.put("history", this.history);
        map.put("stream", this.stream);
        map.put("model_name", this.modelName);
        map.put("temperature", this.temperature);
        map.put("max_tokens", this.maxTokens);
        map.put("prompt_name", this.promptName);
        map.put("split_result", this.splitResult);
        return map;
    }

    private SearchEngineChatRequest() {
    }

    /**
     * 新增
     *
     * @param query
     * @param searchEngineName
     * @param topK
     * @param stream
     * @param modelName
     * @param temperature
     * @param maxTokens
     * @param promptName
     * @param splitResult
     */
    public SearchEngineChatRequest(String query, String searchEngineName, Integer topK, Boolean stream, String modelName, BigDecimal temperature, Integer maxTokens, String promptName, Boolean splitResult) {
        this.query = query;
        this.searchEngineName = searchEngineName;
        this.topK = topK;
        this.stream = stream;
        this.modelName = modelName;
        this.temperature = temperature;
        this.maxTokens = maxTokens;
        this.promptName = promptName;
        this.splitResult = splitResult;
    }

    /**
     * 查询语句
     */
    private String query;
    /**
     * 搜索引擎名称
     */
    private String searchEngineName;
    /**
     *
     */
    private Integer topK;
    /**
     * 历史记录
     */
    private List<History> history;
    /**
     * 是否启用流式输出
     */
    private Boolean stream;
    /**
     * 模型名称
     */
    private String modelName;
    /**
     *
     */
    private BigDecimal temperature;
    /**
     * 最大字数
     */
    private Integer maxTokens;
    /**
     * 提示词名称
     */
    private String promptName;
    /**
     * 是否分割结果
     */
    private Boolean splitResult;

}
