package com.moka.gdtauto.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;

import org.bytedeco.librealsense2.rs2_firmware_log_message;
import org.springframework.stereotype.Service;

import com.moka.gdtauto.client.TencentAdsApiClientFactory;
import com.moka.gdtauto.common.Constant;
import com.moka.gdtauto.entity.OssFile;
import com.tencent.ads.model.v3.BrandAddResponseData;
import com.tencent.ads.model.v3.ImagesAddResponseData;
import com.tencent.ads.model.v3.VideosAddResponseData;
import com.tencent.ads.v3.TencentAds;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
@AllArgsConstructor
public class TencentAssetService {
    private TencentAdsApiClientFactory clientFactory;

    public void uploadAsset(OssFile ossFile) throws Exception {
        // 只支持创意上传
        if (ossFile.getBusinessType() != 1) {
            return;
        }
        log.info("开始上传文件到腾讯广告，ID: {}", ossFile.getId());
        TencentAds tencentAds = clientFactory.getTencentAds("", Constant.MAIN_ORG_ACCOUNT_ID);
        String fileUrl = ossFile.getFileUrl();
        String fileMd5 = ossFile.getFileMd5();
        // image/video
        String fileType = ossFile.getFileType();
        if (fileType.equals("image")) {
            try {
                byte[] fileBytes = downloadFileToBytes(fileUrl);
                ImageUploadResult result = uploadImageFromBytes(tencentAds, fileBytes, fileMd5, fileType);
                ossFile.setAssetId(result.imageId);
                ossFile.setWidth(result.width);
                ossFile.setHeight(result.height);
                ossFile.setImageFileSize(result.imageFileSize);
                ossFile.setImageType(result.imageType);
                ossFile.setImageSignature(result.imageSignature);
                ossFile.setOuterImageId(result.outerImageId);
                ossFile.setPreviewUrl(result.previewUrl);
                ossFile.setDescription(result.description);
            } catch (Exception e) {
                log.error("上传文件失败，URL: {}", fileUrl, e);
            }
        } else if (fileType.equals("video")) {
            try {
               VideoUploadResult result =  uploadVideoFromUrl(tencentAds, fileUrl, fileMd5, fileType);
               ossFile.setAssetId(String.valueOf(result.videoId));
               ossFile.setCoverImageId(result.coverImageId);
            } catch (Exception e) {
                log.error("上传文件失败，URL: {}", fileUrl, e);
            }
        }
    }

    public ImageUploadResult uploadImageFromBytes(TencentAds tencentAds, byte[] imageBytes, String fileMd5,
            String description)
            throws Exception {
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        ImagesAddResponseData response = tencentAds.images()
                .imagesAdd(
                        "UPLOAD_TYPE_BYTES",
                        fileMd5,
                        null,
                        Constant.MAIN_ORG_ACCOUNT_ID,
                        null,
                        base64Image,
                        null,
                        description,
                        null,
                        null,
                        null);

        if (response == null || response.getImageId() == null) {
            throw new Exception("图片上传返回结果为空");
        }

        log.info("图片上传成功，imageId: {}, 宽度: {}px, 高度: {}px",
                response.getImageId(), response.getImageWidth(), response.getImageHeight());

        return new ImageUploadResult(
                response.getImageId(),
                response.getImageWidth(),
                response.getImageHeight(),
                response.getImageFileSize(),
                response.getImageType().getValue(),
                response.getImageSignature(),
                response.getOuterImageId(),
                response.getPreviewUrl(),
                response.getDescription());
    }

    public record ImageUploadResult(
            String imageId,
            /**
             * 图片宽度
             */
            Long width,
            /**
             * 图片高度
             */
            Long height,
            /**
             * 图片大小
             */
            Long imageFileSize,
            /**
             * 图片类型
             */
            String imageType,
            /**
             * 图片签名
             */
            String imageSignature,
            /**
             * 外部图片ID
             */
            String outerImageId,
            /**
             * 预览地址
             */
            String previewUrl,
            /**
             * 图片描述
             */
            String description) {
    }

    /**
     * 视频上传结果记录
     */
    public record VideoUploadResult(Long videoId, Long coverImageId) {
    }

    /**
     * 品牌形象上传结果记录
     */
    public record BrandUploadResult(Long imageId, Long width, Long height) {
    }

    /**
     * 从URL下载品牌形象并上传到腾讯广告（返回完整信息）
     * 品牌形象不支持业务单元ID上传
     *
     * @param tencentAds    腾讯广告SDK实例
     * @param accountId     账户ID
     * @param brandImageUrl 品牌形象图片URL
     * @param fileMd5       文件MD5
     * @param brandName     品牌名称
     * @return 品牌形象上传结果
     * @throws Exception 上传失败
     */
    public BrandUploadResult uploadBrandImageFromUrl(TencentAds tencentAds, Long accountId, String brandImageUrl, String fileMd5, String brandName)
            throws Exception {
        File tempFile = null;
        try {
            // 1. 从URL下载图片到临时文件
            tempFile = downloadFileFromUrl(brandImageUrl);

            // 2. 调用腾讯广告API创建品牌形象
            BrandAddResponseData response = tencentAds.brand()
                    .brandAdd(
                            accountId, // accountId
                            brandName, // name
                            tempFile // brandImageFile
                    );

            if (response == null || response.getImageId() == null) {
                throw new Exception("品牌形象上传返回结果为空");
            }

            log.info("品牌形象上传成功，imageId: {}, 品牌名称: {}, 宽度: {}px, 高度: {}px",
                    response.getImageId(), response.getName(), response.getWidth(), response.getHeight());

            return new BrandUploadResult(
                    Long.parseLong(response.getImageId()),
                    response.getWidth(),
                    response.getHeight()
            );

        } finally {
            // 3. 删除临时文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    public VideoUploadResult uploadVideoFromUrl(TencentAds tencentAds,  String videoUrl, String fileMd5,  String description)
            throws Exception {
        File tempFile = null;
        try {
            // 1. 从URL下载视频到临时文件
            tempFile = downloadFileFromUrl(videoUrl);

            // 2. 检查文件大小（最大100MB）
            long fileSizeInMB = tempFile.length() / (1024 * 1024);
            if (fileSizeInMB > 100) {
                throw new Exception("视频文件过大: " + fileSizeInMB + "MB，超过 100MB 限制");
            }

            // 3. 计算视频MD5签名
            String signature = fileMd5;
            log.info("视频MD5签名: {}, 文件大小: {}MB", signature, fileSizeInMB);

            // 4. 调用腾讯广告API上传视频
            VideosAddResponseData response = tencentAds.videos()
                    .videosAdd(
                            tempFile, // videoFile
                            signature, // signature
                            null, // accountId
                            Constant.MAIN_ORG_ACCOUNT_ID, // organizationId
                            description, // description
                            null // adcreativeTemplateId
                    );

            if (response == null || response.getVideoId() == null) {
                throw new Exception("视频上传返回结果为空");
            }

            log.info("视频上传成功，videoId: {}, 封面图片ID: {}",
                    response.getVideoId(), response.getCoverImageId());
            return new VideoUploadResult(response.getVideoId(), response.getCoverImageId());
        } finally {
            // 5. 删除临时文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }

    private File downloadFileFromUrl(String fileUrl) throws Exception {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        FileOutputStream outputStream = null;

        try {
            // 创建临时文件
            String suffix = getFileSuffix(fileUrl);
            File tempFile = File.createTempFile("gdt_upload_", suffix);

            // 打开HTTP连接
            URL url = new URL(fileUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(30000);
            connection.setRequestMethod("GET");
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new Exception("下载文件失败，HTTP状态码: " + responseCode);
            }

            // 读取文件内容
            inputStream = connection.getInputStream();
            outputStream = new FileOutputStream(tempFile);

            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            log.info("文件下载成功，URL: {}, 大小: {} bytes", fileUrl, tempFile.length());
            return tempFile;

        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    private String getFileSuffix(String fileUrl) {
        int lastDotIndex = fileUrl.lastIndexOf('.');
        int lastSlashIndex = fileUrl.lastIndexOf('/');

        if (lastDotIndex > lastSlashIndex && lastDotIndex < fileUrl.length() - 1) {
            return fileUrl.substring(lastDotIndex);
        }

        return ".mp4"; // 默认后缀
    }

    public byte[] downloadFileToBytes(String fileUrl) throws Exception {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        try {
            URL url = new URL(fileUrl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(30000);
            connection.setRequestMethod("GET");
            connection.connect();

            int responseCode = connection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new Exception("下载文件失败，HTTP状态码: " + responseCode);
            }

            inputStream = connection.getInputStream();
            byte[] fileBytes = inputStream.readAllBytes();
            log.info("文件下载成功，URL: {}, 大小: {} bytes", fileUrl, fileBytes.length);
            return fileBytes;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.warn("关闭输入流失败", e);
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
}
