package com.moka.gdtauto.service;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.moka.gdtauto.GdtAutoApplication;
import com.moka.gdtauto.client.TencentAdsApiClientFactory;
import com.tencent.ads.model.v3.ImagesAddResponseData;
import com.tencent.ads.v3.TencentAds;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.Base64;

/**
 * 腾讯广告图片上传测试
 * https://developers.e.qq.com/v3.0/docs/api/images/add
 * @author moka
 * @since 2026-02-06
 */
@SpringBootTest(classes = GdtAutoApplication.class)
@ActiveProfiles("test")
class TencentImagesAddTest {

    @Autowired
    private TencentAdsApiClientFactory clientFactory;

    private static final Long ORG_ACCOUNT_ID = 33453856L;
    private static final Long TEST_ACCOUNT_ID = 69781948L;
    private static final String TEST_JOB_NUMBER = "12458";

    @Test
    @DisplayName("测试上传图片文件-使用文件方式")
    void testUploadImageFile() {
        System.out.println("\n========================================");
        System.out.println("开始上传图片文件");
        System.out.println("账户ID: " + TEST_ACCOUNT_ID);
        System.out.println("========================================\n");

        try {
            // 获取TencentAds实例
            TencentAds tencentAds = clientFactory.getTencentAds(TEST_JOB_NUMBER, ORG_ACCOUNT_ID);
            tencentAds.setDebug(true);

            // 图片文件路径（请替换为实际图片路径）
            String imagePath = "/Users/pudongliang/moka_workspace/gdt-auto/test.jpeg";
            File imageFile = new File(imagePath);
            
            if (!imageFile.exists()) {
                System.err.println("❌ 图片文件不存在: " + imagePath);
                System.err.println("请修改 imagePath 为实际的图片文件路径");
                return;
            }

            // 计算图片MD5签名
            String signature = calculateMD5(imageFile);
            System.out.println("图片MD5签名: " + signature);

            String description = "测试上传图片-" + System.currentTimeMillis();
            
            // 输出请求参数
            System.out.println("\n========== 请求参数 ==========");
            System.out.println("账户ID: " + TEST_ACCOUNT_ID);
            System.out.println("上传方式: UPLOAD_TYPE_FILE");
            System.out.println("签名: " + signature);
            System.out.println("文件路径: " + imagePath);
            System.out.println("描述: " + description);
            System.out.println("========================================\n");

            // 调用上传接口
            System.out.println("正在调用腾讯广告上传图片API...");
            ImagesAddResponseData response = tencentAds.images()
                .imagesAdd(
                    "UPLOAD_TYPE_FILE",  // uploadType
                    signature,            // signature
                    TEST_ACCOUNT_ID,      // accountId
                    null,                 // organizationId
                    imageFile,            // file
                    null,                 // bytes
                    null,                 // imageUsage
                    description,          // description
                    null,                 // resizeWidth
                    null,                 // resizeHeight
                    null                  // resizeFileSize
                );

            // 输出响应结果
            System.out.println("\n========== API返回结果 ==========");
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            System.out.println(gson.toJson(response));
            System.out.println("========================================\n");

            // 输出摘要信息
            if (response != null) {
                System.out.println("✅ 成功上传图片");
                System.out.println("📊 图片ID: " + response.getImageId());
                System.out.println("📊 图片宽度: " + response.getImageWidth() + "px");
                System.out.println("📊 图片高度: " + response.getImageHeight() + "px");
                System.out.println("📊 图片大小: " + response.getImageFileSize() + "B");
                System.out.println("📊 图片类型: " + response.getImageType());
                System.out.println("📊 预览地址: " + response.getPreviewUrl());
            } else {
                System.out.println("⚠️  返回结果为空");
            }

        } catch (Exception e) {
            System.err.println("\n❌ API调用失败");
            System.err.println("错误信息: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("测试失败", e);
        }
    }

    @Test
    @DisplayName("测试上传图片文件-使用Base64方式")
    void testUploadImageBytes() {
        System.out.println("\n========================================");
        System.out.println("开始上传图片文件(Base64)");
        System.out.println("账户ID: " + TEST_ACCOUNT_ID);
        System.out.println("========================================\n");

        try {
            // 获取TencentAds实例
            TencentAds tencentAds = clientFactory.getTencentAds(TEST_JOB_NUMBER, ORG_ACCOUNT_ID);
            tencentAds.setDebug(true);

            // 图片文件路径（请替换为实际图片路径）
            String imagePath = "/path/to/your/image.jpg";
            File imageFile = new File(imagePath);
            
            if (!imageFile.exists()) {
                System.err.println("❌ 图片文件不存在: " + imagePath);
                System.err.println("请修改 imagePath 为实际的图片文件路径");
                return;
            }

            // 读取图片并转Base64
            byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            
            // 计算图片MD5签名
            String signature = calculateMD5(imageFile);
            System.out.println("图片MD5签名: " + signature);
            System.out.println("图片Base64长度: " + base64Image.length());

            String description = "测试上传图片Base64-" + System.currentTimeMillis();
            
            // 输出请求参数
            System.out.println("\n========== 请求参数 ==========");
            System.out.println("账户ID: " + TEST_ACCOUNT_ID);
            System.out.println("上传方式: UPLOAD_TYPE_BYTES");
            System.out.println("签名: " + signature);
            System.out.println("Base64长度: " + base64Image.length());
            System.out.println("描述: " + description);
            System.out.println("========================================\n");

            // 调用上传接口
            System.out.println("正在调用腾讯广告上传图片API...");
            ImagesAddResponseData response = tencentAds.images()
                .imagesAdd(
                    "UPLOAD_TYPE_BYTES", // uploadType
                    signature,            // signature
                    TEST_ACCOUNT_ID,      // accountId
                    null,                 // organizationId
                    null,                 // file
                    base64Image,          // bytes
                    null,                 // imageUsage
                    description,          // description
                    null,                 // resizeWidth
                    null,                 // resizeHeight
                    null                  // resizeFileSize
                );

            // 输出响应结果
            System.out.println("\n========== API返回结果 ==========");
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            System.out.println(gson.toJson(response));
            System.out.println("========================================\n");

            // 输出摘要信息
            if (response != null) {
                System.out.println("✅ 成功上传图片");
                System.out.println("📊 图片ID: " + response.getImageId());
                System.out.println("📊 图片宽度: " + response.getImageWidth() + "px");
                System.out.println("📊 图片高度: " + response.getImageHeight() + "px");
                System.out.println("📊 图片大小: " + response.getImageFileSize() + "B");
                System.out.println("📊 图片类型: " + response.getImageType());
                System.out.println("📊 预览地址: " + response.getPreviewUrl());
            } else {
                System.out.println("⚠️  返回结果为空");
            }

        } catch (Exception e) {
            System.err.println("\n❌ API调用失败");
            System.err.println("错误信息: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("测试失败", e);
        }
    }

    @Test
    @DisplayName("测试上传图片并指定尺寸")
    void testUploadImageWithResize() {
        System.out.println("\n========================================");
        System.out.println("开始上传图片文件(指定尺寸)");
        System.out.println("账户ID: " + TEST_ACCOUNT_ID);
        System.out.println("========================================\n");

        try {
            // 获取TencentAds实例
            TencentAds tencentAds = clientFactory.getTencentAds(TEST_JOB_NUMBER, ORG_ACCOUNT_ID);
            tencentAds.setDebug(true);

            // 图片文件路径（请替换为实际图片路径）
            String imagePath = "/path/to/your/image.jpg";
            File imageFile = new File(imagePath);
            
            if (!imageFile.exists()) {
                System.err.println("❌ 图片文件不存在: " + imagePath);
                System.err.println("请修改 imagePath 为实际的图片文件路径");
                return;
            }

            // 计算图片MD5签名
            String signature = calculateMD5(imageFile);
            String description = "测试上传图片并调整尺寸-" + System.currentTimeMillis();
            Long resizeWidth = 800L;
            Long resizeHeight = 600L;
            
            // 输出请求参数
            System.out.println("\n========== 请求参数 ==========");
            System.out.println("账户ID: " + TEST_ACCOUNT_ID);
            System.out.println("上传方式: UPLOAD_TYPE_FILE");
            System.out.println("签名: " + signature);
            System.out.println("文件路径: " + imagePath);
            System.out.println("目标宽度: " + resizeWidth + "px");
            System.out.println("目标高度: " + resizeHeight + "px");
            System.out.println("图片用途: IMAGE_USAGE_DEFAULT");
            System.out.println("描述: " + description);
            System.out.println("========================================\n");

            // 调用上传接口
            System.out.println("正在调用腾讯广告上传图片API...");
            ImagesAddResponseData response = tencentAds.images()
                .imagesAdd(
                    "UPLOAD_TYPE_FILE",      // uploadType
                    signature,                // signature
                    TEST_ACCOUNT_ID,          // accountId
                    null,                     // organizationId
                    imageFile,                // file
                    null,                     // bytes
                    "IMAGE_USAGE_DEFAULT",   // imageUsage
                    description,              // description
                    resizeWidth,              // resizeWidth
                    resizeHeight,             // resizeHeight
                    null                      // resizeFileSize
                );

            // 输出响应结果
            System.out.println("\n========== API返回结果 ==========");
            Gson gson = new GsonBuilder().setPrettyPrinting().create();
            System.out.println(gson.toJson(response));
            System.out.println("========================================\n");

            // 输出摘要信息
            if (response != null) {
                System.out.println("✅ 成功上传图片");
                System.out.println("📊 图片ID: " + response.getImageId());
                System.out.println("📊 图片宽度: " + response.getImageWidth() + "px");
                System.out.println("📊 图片高度: " + response.getImageHeight() + "px");
                System.out.println("📊 图片大小: " + response.getImageFileSize() + "B");
                System.out.println("📊 图片类型: " + response.getImageType());
                System.out.println("📊 预览地址: " + response.getPreviewUrl());
            } else {
                System.out.println("⚠️  返回结果为空");
            }

        } catch (Exception e) {
            System.err.println("\n❌ API调用失败");
            System.err.println("错误信息: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("测试失败", e);
        }
    }

    /**
     * 计算文件的MD5签名
     */
    private String calculateMD5(File file) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                md.update(buffer, 0, bytesRead);
            }
        }
        byte[] digest = md.digest();
        BigInteger bigInt = new BigInteger(1, digest);
        String hashtext = bigInt.toString(16);
        // 补齐前导0
        while (hashtext.length() < 32) {
            hashtext = "0" + hashtext;
        }
        return hashtext;
    }
}
