package com.cmvr.llm.util;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.volcengine.auth.ISignerV4;
import com.volcengine.auth.impl.SignerV4Impl;
import com.volcengine.model.Credentials;
import com.volcengine.service.SignableRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.util.Asserts;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 大模型文件上传工具类。
 * 用于处理大模型相关接口中涉及文件上传的场景。该工具类封装了文件上传逻辑，
 * 并返回可用于后续调用的文件下载链接。大模型服务可通过该链接获取上传的文件进行处理。
 * 使用方式：
 * 1. 调用 {@link #uploadFile(byte[])} 方法上传文件数据；
 * 2. 获取返回的文件下载 URL；
 * 3. 将该 URL 作为参数传递给大模型接口进行后续处理。
 * 注：文件与2小时过期
 */
public class LargeModelFileUploadUtil {

    public static final String ACCESS_KEY_ID = "AKLTZjdkZThhNzk0MjFlNDI5ZWJiYWZiYzQzM2Q0ZTYzOTg";
    public static final String SECRET_ACCESS_KEY = "WlRrMVlqa3dOakkzTUdZMU5EbGpZV0ptWm1SbE1qRXlNR1ptWmpjMU56TQ==";
    public static final String HOST = "https://opensseapi.cmhk.com/aiagentplatformSDK_v1/aiagentplatformSDK/up";
    public static final String VERSION = "2022-01-01";
    public static final String SERVICE_NAME = "app";
    public static final String ACTION_NAME = "UploadRaw";
    // 过期时间2小时
    private static final String EXPIRE = "2h";
    private static final String REGION = "cn-north-1";
    private static final String BASE_DOWNLOAD_URL = "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01";
    private static final String X_GATEWAY_APIKEY = "Bearer ZjhiODA1MDctYzJjOS00MTEzLWI0ZGYtNTQ4ZTc3MTk1MTAz";

    private static final Logger logger = Logger.getLogger(LargeModelFileUploadUtil.class.getName());

    // 私有构造函数防止实例化
    private LargeModelFileUploadUtil() {
        throw new UnsupportedOperationException("Utility class");
    }

    /**
     * 发送字节数据并返回下载URL
     *
     * @param data 字节数据
     * @return 下载URL
     * @throws Exception 异常
     */
    public static String uploadFile(byte[] data) throws Exception {
        SignableRequest signableRequest = getSignableRequest(data);
        ISignerV4 signer = new SignerV4Impl();
        Credentials credentials = initCredentials();
        signer.sign(signableRequest, credentials);
        Asserts.notNull(signableRequest, "signableRequest can not null");

        String contentSha256 = DigestUtil.sha256Hex(data);

        HttpResponse response = HttpRequest.post(signableRequest.getURI().toString())
                .header("Content-Type", ContentType.APPLICATION_JSON.getMimeType())
                .header("x-gateway-apikey", X_GATEWAY_APIKEY)
                .header("X-Content-Sha256", contentSha256)
                .body(data)
                .execute();

        return buildDownloadUrl(response.body());
    }

    /**
     * 初始化凭证
     *
     * @return 凭证对象
     */
    private static Credentials initCredentials() {
        Credentials credentials = new Credentials();
        credentials.setAccessKeyID(ACCESS_KEY_ID);
        credentials.setSecretAccessKey(SECRET_ACCESS_KEY);
        credentials.setRegion(REGION);
        credentials.setService(SERVICE_NAME);
        return credentials;
    }

    /**
     * 获取签名请求
     *
     * @param data 请求数据
     * @return 签名请求
     * @throws URISyntaxException URI语法异常
     */
    private static @NotNull SignableRequest getSignableRequest(byte[] data) throws URISyntaxException {
        String url = buildUrl();
        SignableRequest signableRequest = new SignableRequest();
        signableRequest.setMethod("POST");
        URIBuilder uriBuilder = new URIBuilder(url);
        signableRequest.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
        signableRequest.setHeader("x-gateway-apikey", X_GATEWAY_APIKEY);
        signableRequest.setEntity(new ByteArrayEntity(data, ContentType.APPLICATION_JSON));
        signableRequest.setUriBuilder(uriBuilder);
        signableRequest.setURI(uriBuilder.build());
        return signableRequest;
    }

    /**
     * 构建请求URL
     *
     * @return 请求URL
     */
    private static String buildUrl() {
        return HOST + "?Expire=" + EXPIRE + "&Action=" + ACTION_NAME + "&Version=" + VERSION + "&Id=" + "8a2c5aa0-6e62-c405-6150-a3136146a616";
    }

    /**
     * 构建下载URL
     *
     * @param responseBody 响应体
     * @return 下载URL
     */
    private static String buildDownloadUrl(String responseBody) {
        try {
            JSONObject result = JSON.parseObject(responseBody).getJSONObject("Result");
            if (result == null || !result.containsKey("Path")) {
                logger.warning("Result or Path is missing in response body.");
                return null;
            }

            Object pathObj = result.get("Path");
            if (pathObj == null) {
                logger.warning("Path value is null.");
                return null;
            }

            String path = pathObj.toString();
            String encodedPath = URLEncoder.encode(path, "UTF-8");

            return BASE_DOWNLOAD_URL + "&Path=" + encodedPath + "&IsAnonymous=true";
        } catch (UnsupportedEncodingException e) {
            logger.severe("Encoding failed: " + e.getMessage());
            return null;
        } catch (Exception e) {
            logger.severe("Error parsing response body: " + e.getMessage());
            return null;
        }
    }

    public static String getStringFromFile(String filePath) throws IOException {
        return new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
    }

    public static void main(String[] args) throws Exception {

        // 1. 构建请求体
        String knowledgeBasePath = "D:\\desktop\\test.txt"; // 确保这是正确的路径
        String knowledgeBasePath2 = "D:\\desktop\\test.json"; // 确保这是正确的路径
        String knowledgeBaseContent = getStringFromFile(knowledgeBasePath);
        String knowledgeBaseContent2 = getStringFromFile(knowledgeBasePath2);

        Map<String, Object> messages = new HashMap<>();
        messages.put("role", "system");
        messages.put("content", knowledgeBaseContent);

        Map<String, Object> messages2 = new HashMap<>();
        messages.put("role", "system");
        messages.put("content", knowledgeBaseContent2);

        Map<String, Object> userMessage = new HashMap<>();
        userMessage.put("role", "user");
        userMessage.put("content", "根据知识库回答，我现在在首页，我需要打开空调");
        List<Map<String, Object>> messageList = new ArrayList<>();
        messageList.add( messages);
        messageList.add( messages2);
        messageList.add(userMessage);
        Map<String, Object> body = new HashMap<>();
        body.put("messages", messageList);
        body.put("model", "deepseek-r1:7b");
        body.put("stream", false);

        // 2. 发送请求到语音合成服务
        HttpResponse response = HttpRequest.post("http://10.148.108.16:11434/api/chat")
                .header("Content-Type", "application/json")
                .body(com.alibaba.fastjson2.JSON.toJSONString(body))
                .execute();
        System.out.println(response);
    }

}