package com.backendsys.service.SDKService.SDKTencent;

import cn.hutool.core.convert.Convert;
import com.backendsys.entity.SDKEntity.TencentCOSCredentialsDTO;
import com.backendsys.exception.CustException;
import com.backendsys.utils.MapUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicSessionCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import com.qcloud.cos.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class SDKTencentAiServiceImpl implements SDKTencentAiService {

    /**
     * 文档中心 > 腾讯云智能数智人 > API 接入 > 视频生成服务 API 文档-v4.9.7 > 数智人 aPaas 接口调用方式
     * https://cloud.tencent.com/document/product/1240/83535
     */

    @Value("${tencent.ivh.app-key}")
    private String appKey;

    @Value("${tencent.ivh.access-token}")
    private String accessToken;

    @Autowired
    private SDKTencentService sdkTencentService;

    @Autowired
    private SDKTencentCOSService sdkTencentCOSService;


    /**
     * 统一请求返回体封装 (腾讯云-数智人)
     */
    public Map<String, Object> checkResp(Map<String, Object> resp) {
        if (resp != null && !resp.isEmpty()) {
            Integer respHeaderCode = (Integer) MapUtil.get(resp, "Header.Code");
            if (respHeaderCode != 0) {
                String respHeaderMessage = (String) MapUtil.get(resp, "Header.Message");
                System.out.println(resp);
                throw new CustException("(" + respHeaderCode + ") " + respHeaderMessage);
            }
//            Map<String, Object> respPayload = (Map<String, Object>) resp.get("Payload");
            Map<String, Object> respPayload = Convert.toMap(String.class, Object.class, resp.get("Payload"));

            return respPayload;
        }
        throw new CustException("resp is null");
    }


    /**
     * [腾讯-数智人] 上传素材文件 (临时目录)
     */
    @Transactional(rollbackFor = Exception.class)
    public UploadResult uploadTemp(MultipartFile file, String type, String fileTargetPath) {

        // 获得临时密钥
        TencentCOSCredentialsDTO credentialsDTO = sdkTencentCOSService.getIvhTempCredentials(appKey, accessToken);

        // 定义正则表达式，创建Matcher对象
        String pathPrefix = credentialsDTO.getPath_prefix();
        Pattern pattern = Pattern.compile("https://([a-zA-Z0-9\\-]+)\\.cos\\.(\\w+)\\.myqcloud\\.com/.*");
        Matcher matcher = pattern.matcher(pathPrefix);
        if (matcher.find()) {
            String bucket = matcher.group(1);
            String region = matcher.group(2);

            // -- 使用临时密钥创建 COSClient ---------------------------------------------
            COSCredentials cred = new BasicSessionCredentials(credentialsDTO.getTmp_secret_id(), credentialsDTO.getTmp_secret_key(), credentialsDTO.getSession_token());
            ClientConfig clientConfig = new ClientConfig();
            clientConfig.setRegion(new Region(region));

            // 生成cos客户端
            COSClient cosClient = new COSClient(cred, clientConfig);

            // 使用高级接口必须先保证本进程存在一个 TransferManager 实例，如果没有则创建
            TransferManager transferManager = sdkTencentCOSService.createTransferManager(cosClient);

            try {

                // 获取文件内容
                InputStream inputStream = file.getInputStream();

                // 将文件内容写入临时文件
                File tempFile = File.createTempFile("temp", null);
                try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
                    IOUtils.copy(inputStream, outputStream);
                }

                /**
                 * Access Denied. 注意 《使用临时密钥操作时报错 403，该如何处理？》
                 * https://cloud.tencent.com/document/product/436/56530
                 */
                // 找到 "customer-pipeline" 的索引，从索引开始截取直到字符串结束：
                // 输出：customer-pipeline/884/8469c837-c272-42b3-85db-9395c9d19e8c/
                // String key = "customer-pipeline/884/4b4f2948-3fca-4350-8d05-e569e899d7c9/idcard/b.pdf";
                // String key = "customer-pipeline/884/4b4f2948-3fca-4350-8d05-e569e899d7c9/" + fileTargetPath;
                int startIndex = pathPrefix.indexOf("customer-pipeline");
                String firstPath = pathPrefix.substring(0, startIndex);
                String lastPath = pathPrefix.substring(startIndex);
                String objectName = lastPath + fileTargetPath;

                // 创建 PutObjectRequest 对象。
                // System.out.println("bucket = " + bucket + ", objectName = " + objectName + ", tempFile = " + tempFile);

                PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, tempFile);
                ObjectMetadata objectMetadata = new ObjectMetadata();
                putObjectRequest.withMetadata(objectMetadata);

                // 创建 PutObject 请求。(同步)
                Upload upload = transferManager.upload(putObjectRequest);
                System.out.println("创建 PutObject 请求。(同步)");
                System.out.println(upload);
                UploadResult uploadResult = upload.waitForUploadResult();
                System.out.println(uploadResult);

                uploadResult.setKey(firstPath + uploadResult.getKey());
                return uploadResult;

//                // 创建 PutObject 请求。(异步)
//                PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
//                System.out.println("-- putObjectResult: --------------------------------");
//                System.out.println(putObjectResult);
//                System.out.println(putObjectResult.toString());
//                System.out.println(putObjectResult.getRequestId());

            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
//                if (cosClient != null) cosClient.shutdown();
                sdkTencentCOSService.shutdownTransferManager(transferManager);
            }

        }
        return null;
    }

}
