package com.moka.gdtauto.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moka.gdtauto.entity.AdPlanConf;
import com.moka.gdtauto.mapper.AdPlanConfMapper;
import com.moka.gdtauto.service.AdPlanConfService;
import com.moka.gdtauto.service.AdPlanCreativeService;
import com.moka.gdtauto.service.TencentAdsAdgroupService;
import com.moka.gdtauto.service.TencentAccountService;
import com.moka.gdtauto.client.TencentAdsApiClientFactory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.ArrayList;
import com.moka.gdtauto.entity.AdPlan;
import com.moka.gdtauto.entity.AdPlanCreative;
import com.moka.gdtauto.service.AdPlanService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;

import com.tencent.ads.model.v3.*;
import com.tencent.ads.v3.TencentAds;
import com.moka.gdtauto.util.AdgroupsAddReqPool;
import com.moka.gdtauto.common.AdPlanStatus;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.util.Base64;



/**
 * 广告计划配置服务实现类
 * 
 * @author moka
 * @since 2026-02-24
 */
@Slf4j
@Service
public class AdPlanConfServiceImpl extends ServiceImpl<AdPlanConfMapper, AdPlanConf> implements AdPlanConfService {

    @Autowired
    private AdPlanService adPlanService; 
    @Autowired
    private AdPlanCreativeService adPlanCreativeService;
    @Autowired
    private TencentAdsAdgroupService tencentAdsAdgroupService;
    @Autowired
    private TencentAdsApiClientFactory clientFactory;
    @Autowired
    private TencentAccountService tencentAccountService;

    private static final Long MAIN_ORG_ACCOUNT_ID = 41644744L;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createAdPlanConf(AdPlanConf adPlanConf) {
        adPlanConf.setCreateTime(LocalDateTime.now());
        adPlanConf.setUpdateTime(LocalDateTime.now());
        adPlanConf.setDeleted(0);
        
        this.save(adPlanConf);
        log.info("创建广告计划配置成功，配置ID: {}, 配置名称: {}", adPlanConf.getId(), adPlanConf.getName());
        
        return adPlanConf.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAdPlanConf(AdPlanConf adPlanConf) {
        AdPlanConf existingConf = this.getOne(new LambdaQueryWrapper<AdPlanConf>()
                .eq(AdPlanConf::getId, adPlanConf.getId())
                .eq(AdPlanConf::getDeleted, 0));
        
        if (existingConf == null) {
            log.warn("广告计划配置不存在或无权限，配置ID: {}, 用户ID: {}", adPlanConf.getId(), adPlanConf.getUserId());
            return false;
        }
        
        adPlanConf.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(adPlanConf);
        log.info("更新广告计划配置成功，配置ID: {}", adPlanConf.getId());
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAdPlanConf(Long confId, Long userId) {
        AdPlanConf existingConf = this.getOne(new LambdaQueryWrapper<AdPlanConf>()
                .eq(AdPlanConf::getId, confId)
                .eq(AdPlanConf::getUserId, userId)
                .eq(AdPlanConf::getDeleted, 0));
        
        if (existingConf == null) {
            log.warn("广告计划配置不存在或无权限，配置ID: {}, 用户ID: {}", confId, userId);
            return false;
        }
        
        existingConf.setDeleted(1);
        existingConf.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(existingConf);
        
        log.info("删除广告计划配置成功，配置ID: {}", confId);
        return result;
    }

    @Override
    public Page<AdPlanConf> getUserAdPlanConfs(Long userId, Integer pageNum, Integer pageSize) {
        Page<AdPlanConf> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<AdPlanConf> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdPlanConf::getDeleted, 0)
                .orderByDesc(AdPlanConf::getCreateTime);
        
        return this.page(page, queryWrapper);
    }

    @Override
    public AdPlanConf getAdPlanConfById(Long confId, Long userId) {
        return this.getOne(new LambdaQueryWrapper<AdPlanConf>()
                .eq(AdPlanConf::getId, confId)
                .eq(AdPlanConf::getDeleted, 0));
    }

    @Override
    public void generatePlan(List<AdPlan> plans) {
        // 实现生成计划的逻辑
        log.info("生成计划，计划列表: {}", plans);
        for (AdPlan plan : plans) {
            adPlanService.save(plan);
            Long planId = plan.getId();

            plan.getAdCreatives().forEach(adPlanCreative -> {
                adPlanCreative.setAdPlanId(planId);
                adPlanCreative.setAdPlanConfId(plan.getAdPlanConfId());
                adPlanCreative.setAccountId(plan.getAccountId());
                adPlanCreativeService.save(adPlanCreative);
            });
        }
    }

    @Async
    @Override
    public void asyncReGeneratePlan(Long confId) {
        log.info("异步重新生成计划开始，配置ID: {}", confId);
        // 根据配置ID获取计划列表
        AdPlanConf conf = this.getById(confId);
        List<AdPlan> plans = adPlanService.getPlansByConfId(confId);
        plans.forEach(plan -> {
            plan.setConversionId(conf.getConversionId());
            plan.setDramaId(conf.getDramaId());
            plan.setWxCorpid(conf.getWxCorpid());
            plan.setBidAmount(conf.getBidAmount());
        });
        adPlanService.updateBatchById(plans);
        List<AdPlanCreative> creatives = adPlanCreativeService.getCreativesByConfId(confId);
        creatives.forEach(creative -> {
            creative.setBrandName(conf.getBrandName());
            creative.setCreativeText(conf.getCreativeText());
            creative.setButtonText(conf.getButtonText());
        });
        //group by planId
        Map<Long, List<AdPlanCreative>> creativeMap = creatives.stream().collect(Collectors.groupingBy(AdPlanCreative::getAdPlanId));
        for (AdPlan plan : plans) {
            plan.setAdCreatives(creativeMap.getOrDefault(plan.getId(), new ArrayList<AdPlanCreative>()));
        }
        asyncTencentInterface(plans);
    }

    @Async
    @Override
    public void asyncTencentInterface(List<AdPlan> plans) {
        log.info("异步对接腾讯接口开始，计划数量: {}", plans.size());
        
        if (plans == null || plans.isEmpty()) {
            log.warn("计划列表为空，无需处理");
            return;
        }
        
        // 获取配置信息
        Long confId = plans.get(0).getAdPlanConfId();
        AdPlanConf conf = this.getById(confId);
        if (conf == null) {
            log.error("未找到广告计划配置，confId={}", confId);
            return;
        }
        
        String jobNumber = conf.getJobNumber();
        
        // 遍历处理每个 AdPlan
        for (AdPlan plan : plans) {
            try {
                log.info("开始处理广告计划，planId={}, adgroupName={}", plan.getId(), plan.getAdgroupName());
                
                if (plan.getAdgroupId() > 0 || plan.getStatus() == AdPlanStatus.SUCCESS) {
                     // 创建动态创意
                    createDynamicCreatives(plan, jobNumber, MAIN_ORG_ACCOUNT_ID);
                    plan.setFailReason("");
                    plan.setStatus(AdPlanStatus.SUCCESS);
                    plan.setSuccessTime(LocalDateTime.now());
                    adPlanService.updateById(plan);
                    continue;
                }
                    

                // 更新状态为执行中
                plan.setStatus(AdPlanStatus.IN_PROGRESS);
                adPlanService.updateById(plan);
                
                // 根据 adType 构建请求
                AdgroupsAddRequest request = buildAdgroupRequest(plan);
                
                // 创建广告组
                log.info("调用腾讯API创建广告组，accountId={}, orgAccountId={}", plan.getAccountId(), MAIN_ORG_ACCOUNT_ID);
                AdgroupsAddResponseData response = tencentAdsAdgroupService.createAdgroup(
                    jobNumber, MAIN_ORG_ACCOUNT_ID, request
                );
                
                // 更新 adgroupId
                plan.setAdgroupId(response.getAdgroupId());
                log.info("广告组创建成功，adgroupId={}", response.getAdgroupId());

                 // 更新状态为成功
                plan.setStatus(AdPlanStatus.SUCCESS);
                plan.setFailReason("");
                plan.setSuccessTime(LocalDateTime.now());
                adPlanService.updateById(plan);
                
                // 创建动态创意
                if (plan.getAdgroupId() > 0) {
                    createDynamicCreatives(plan, jobNumber, MAIN_ORG_ACCOUNT_ID);
                }
                
                log.info("广告计划处理成功，planId={}, adgroupId={}", plan.getId(), plan.getAdgroupId());
                
            } catch (Exception e) {
                // 记录失败
                log.error("创建广告失败, planId={}", plan.getId(), e);
                plan.setStatus(AdPlanStatus.FAILED);
                plan.setFailReason(truncateError(e.getMessage()));
                adPlanService.updateById(plan);
            }
        }
        
        // 更新 AdPlanConf 状态
        updateAdPlanConfStatus(confId, plans);
        
        log.info("异步对接腾讯接口完成，confId={}", confId);
    }
    
    /**
     * 构建广告组请求
     */
    private AdgroupsAddRequest buildAdgroupRequest(AdPlan plan) {
        if (plan.getAdType() == 1) {
            // 企微广告
            return AdgroupsAddReqPool.getAdgroupsAddRequest(
                plan.getAccountId(),
                plan.getAdgroupName(),
                plan.getWxCorpid(),
                calculateBeginDate(),
                "",
                parseTargetConfId(plan.getTarget()),
                parseSiteConfId(plan.getSite()),
                plan.getBidAmount(),
                plan.getConversionId()
            );
        } else {
            // ROI广告
            return AdgroupsAddReqPool.getROIAdgroupsAddRequest(
                plan.getAccountId(),
                plan.getAdgroupName(),
                plan.getDramaId(),
                calculateBeginDate(),
                "",
                parseTargetConfId(plan.getTarget()),
                parseSiteConfId(plan.getSite()),
                plan.getBidAmount(),
                plan.getConversionId()
            );
        }
    }
    
    /**
     * 创建动态创意
     */
    private void createDynamicCreatives(AdPlan plan, String jobNumber, Long orgAccountId) 
        throws Exception {
        
        TencentAds tencentAds = clientFactory.getTencentAds(jobNumber, orgAccountId);
        
        for (AdPlanCreative creative : plan.getAdCreatives()) {
            try {
                log.info("开始创建动态创意，planId={}, creativeName={}", plan.getId(), creative.getCreativeName());
                
                if (creative.getCreativeId() > 0 || creative.getStatus() == AdPlanStatus.SUCCESS)
                    continue;

                // 更新状态为执行中
                creative.setStatus(AdPlanStatus.IN_PROGRESS);
                creative.setAdgroupId(plan.getAdgroupId());
                adPlanCreativeService.updateById(creative);

                // 上传创意文件的到imageId
                if (creative.getImageId() == 0) {
                    String creativeFileUrl = creative.getCreativeFileUrl();
                    if (creativeFileUrl != null && !creativeFileUrl.isEmpty()) {
                        try {
                            log.info("开始上传创意图片，URL: {}", creativeFileUrl);
                            Long imageId = uploadImageFromUrl(tencentAds, plan.getAccountId(), creativeFileUrl, "创意图片-" + creative.getCreativeName());
                            creative.setImageId(imageId);
                            adPlanCreativeService.updateById(creative);
                            log.info("创意图片上传成功，imageId: {}", imageId);
                        } catch (Exception e) {
                            log.error("创意图片上传失败", e);
                            throw new RuntimeException("创意图片上传失败: " + e.getMessage(), e);
                        }
                    }
                }
                
                if (creative.getBrandImageId() == 0) {
                    // 上传品牌形象
                    String brandImageUrl = creative.getBrandImageUrl();
                    String brandName = creative.getBrandName();
                    if (brandImageUrl != null && !brandImageUrl.isEmpty() 
                        && brandName != null && !brandName.isEmpty()) {
                        try {
                            log.info("开始上传品牌形象，URL: {}, 品牌名称: {}", brandImageUrl, brandName);
                            Long brandImageId = uploadBrandFromUrl(tencentAds, plan.getAccountId(), brandImageUrl, brandName);
                            creative.setBrandImageId(brandImageId);
                            adPlanCreativeService.updateById(creative);
                            log.info("品牌形象上传成功，brandImageId: {}", brandImageId);
                        } catch (Exception e) {
                            log.error("品牌形象上传失败", e);
                            throw new RuntimeException("品牌形象上传失败: " + e.getMessage(), e);
                        }
                    }
                }
                

                // 构建动态创意请求
                DynamicCreativesAddRequest request = buildDynamicCreativeRequest(plan, creative);
                
                // 调用API创建
                DynamicCreativesAddResponseData response = 
                    tencentAds.dynamicCreatives().dynamicCreativesAdd(request);
                
                // 更新创意ID和状态
                creative.setCreativeId(response.getDynamicCreativeId());
                creative.setStatus(AdPlanStatus.SUCCESS);
                creative.setFailReason("");
                creative.setSuccessTime(LocalDateTime.now());
                adPlanCreativeService.updateById(creative);
                
                log.info("动态创意创建成功，creativeId={}", response.getDynamicCreativeId());
                
            } catch (Exception e) {
                log.error("创建动态创意失败, creativeId={}", creative.getId(), e);
                creative.setStatus(AdPlanStatus.FAILED);
                creative.setFailReason(truncateError(e.getMessage()));
                adPlanCreativeService.updateById(creative);
                throw e; // 创意失败则整个广告组失败
            }
        }
    }
    
    /**
     * 构建动态创意请求
     */
    private DynamicCreativesAddRequest buildDynamicCreativeRequest(AdPlan plan, AdPlanCreative creative) {
        DynamicCreativesAddRequest request = new DynamicCreativesAddRequest();
        request.setAccountId(plan.getAccountId());
        request.setAdgroupId(plan.getAdgroupId());
        request.setDynamicCreativeName(creative.getCreativeName());
        request.setDeliveryMode(DeliveryMode.COMPONENT);
        request.setDynamicCreativeType(DynamicCreativeType.PROGRAM);
        
        CreativeComponents components = new CreativeComponents();
        
        // 标题组件 (固定标题)
        components.setTitle(buildTitleComponents(creative.getCreativeText()));
        
        // 文案组件 (固定文案)
        components.setDescription(buildDescriptionComponents(creative.getCreativeText()));
        
        // 图片组件 (从 creative.imageId)
        components.setImage(buildImageComponents(creative.getImageId()));
        
        // 品牌形象 (固定品牌)
        components.setBrand(buildBrandComponents(creative.getBrandImageId(), creative.getBrandName()));
        
        // 落地页 (从 creative.pageIds, 逗号分隔)
        components.setMainJumpInfo(buildJumpInfoComponents(creative.getPageIds()));
        
        // 行动按钮 (数量与落地页一致, 文案统一)
        components.setActionButton(buildActionButtonComponents(creative.getPageIds(), creative.getButtonText()));
        
        request.setCreativeComponents(components);
        return request;
    }
    
    /**
     * 构建标题组件
     */
    private List<TitleComponent> buildTitleComponents(String creativeText) {
        List<TitleComponent> titles = new ArrayList<>();
        
        TitleComponent title1 = new TitleComponent();
        TitleStruct titleValue1 = new TitleStruct();
        titleValue1.setContent(creativeText);
        title1.setValue(titleValue1);
        titles.add(title1);
        
        return titles;
    }
    
    /**
     * 构建文案组件
     */
    private List<DescriptionComponent> buildDescriptionComponents(String creativeText) {
        List<DescriptionComponent> descriptions = new ArrayList<>();
        
        DescriptionComponent desc1 = new DescriptionComponent();
        DescriptionStruct descValue1 = new DescriptionStruct();
        descValue1.setContent(creativeText);
        desc1.setValue(descValue1);
        descriptions.add(desc1);
        
        return descriptions;
    }
    
    /**
     * 构建图片组件
     */
    private List<ImageComponent> buildImageComponents(Long imageId) {
        List<ImageComponent> images = new ArrayList<>();
        ImageComponent image = new ImageComponent();
        ImageStruct imageValue = new ImageStruct();
        imageValue.setImageId(String.valueOf(imageId));
        image.setValue(imageValue);
        images.add(image);
        
        return images;
    }
    
    /**
     * 构建品牌组件
     */
    private List<BrandComponent> buildBrandComponents(Long brandImageId, String brandName) {
        List<BrandComponent> brands = new ArrayList<>();
        
        BrandComponent brand = new BrandComponent();
        BrandStruct brandValue = new BrandStruct();
        brandValue.setBrandName(brandName);
        brandValue.setBrandImageId(String.valueOf(brandImageId));
        brand.setValue(brandValue);
        brands.add(brand);
        
        return brands;
    }
    
    /**
     * 构建落地页组件
     */
    private List<JumpinfoComponent> buildJumpInfoComponents(String pageIds) {
        List<JumpinfoComponent> jumpInfoList = new ArrayList<>();
        
        if (pageIds == null || pageIds.isEmpty()) {
            return jumpInfoList;
        }
        
        String[] pageIdArray = pageIds.split(",");
        for (String pageIdStr : pageIdArray) {
            Long pageId = Long.parseLong(pageIdStr.trim());
            
            JumpinfoComponent jumpinfo = new JumpinfoComponent();
            JumpinfoStruct jumpinfoValue = new JumpinfoStruct();
            PageSpec pageSpec = new PageSpec();
            XjPageSpec xjPageSpec = new XjPageSpec();
            xjPageSpec.setPageId(pageId);
            pageSpec.setOfficialSpec(xjPageSpec);
            jumpinfoValue.setPageSpec(pageSpec);
            jumpinfoValue.setPageType(PageType.OFFICIAL);
            jumpinfo.setValue(jumpinfoValue);
            jumpInfoList.add(jumpinfo);
        }
        
        return jumpInfoList;
    }
    
    /**
     * 构建行动按钮组件
     */
    private List<ActionButtonComponent> buildActionButtonComponents(String pageIds, String buttonText) {
        List<ActionButtonComponent> actionButtons = new ArrayList<>();
        
        if (pageIds == null || pageIds.isEmpty()) {
            return actionButtons;
        }
        
        String[] pageIdArray = pageIds.split(",");
        for (int i = 0; i < pageIdArray.length; i++) {
            ActionButtonComponent actionButton = new ActionButtonComponent();
            ActionButtonStruct actionButtonValue = new ActionButtonStruct();
            actionButtonValue.setButtonText(buttonText);
            actionButton.setValue(actionButtonValue);
            actionButtons.add(actionButton);
        }
        
        return actionButtons;
    }
    
    /**
     * 更新 AdPlanConf 状态
     */
    private void updateAdPlanConfStatus(Long confId, List<AdPlan> plans) {
        // 统计结果
        int totalCount = plans.size();
        int successCount = (int) plans.stream().filter(p -> AdPlanStatus.SUCCESS.equals(p.getStatus())).count();
        int failCount = totalCount - successCount;
        
        // 更新配置状态
        AdPlanConf conf = this.getById(confId);
        if (conf == null) {
            log.warn("未找到广告计划配置，confId={}", confId);
            return;
        }
        
        if (failCount == 0) {
            conf.setStatus(AdPlanStatus.SUCCESS); // 全部成功
            conf.setSuccessTime(LocalDateTime.now());
            conf.setFailReason("");
        } else if (successCount == 0) {
            conf.setStatus(AdPlanStatus.FAILED); // 全部失败
            conf.setFailReason("所有广告创建失败");
        } else {
            conf.setStatus(AdPlanStatus.FAILED); // 部分失败
            conf.setFailReason(String.format("成功%d个,失败%d个", successCount, failCount));
        }
        
        this.updateById(conf);
        log.info("更新广告计划配置状态，confId={}, status={}, 成功:{}, 失败:{}", 
            confId, conf.getStatus(), successCount, failCount);
    }
    
    /**
     * 截断错误信息到200字符
     */
    private String truncateError(String error) {
        if (error == null) {
            return null;
        }
        return error.length() > 200 ? error.substring(0, 200) + "..." : error;
    }
    
    /**
     * 计算开始日期 (明天)
     */
    private String calculateBeginDate() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }
    
    
    /**
     * 解析定向配置ID
     */
    private Integer parseTargetConfId(String target) {
        if (target == null || target.isEmpty()) {
            return 1; // 默认值
        }
        try {
            return Integer.parseInt(target.trim());
        } catch (NumberFormatException e) {
            log.warn("解析定向配置ID失败，使用默认值1，target={}", target);
            return 1;
        }
    }
    
    /**
     * 解析站点配置ID
     */
    private Integer parseSiteConfId(String site) {
        if (site == null || site.isEmpty()) {
            return 1; // 默认值
        }
        try {
            return Integer.parseInt(site.trim());
        } catch (NumberFormatException e) {
            log.warn("解析站点配置ID失败，使用默认值1，site={}", site);
            return 1;
        }
    }
    
    /**
     * 从URL下载图片并上传到腾讯广告
     * 
     * @param tencentAds 腾讯广告SDK实例
     * @param accountId 账户ID
     * @param imageUrl 图片URL
     * @param description 图片描述
     * @return 图片ID
     * @throws Exception 上传失败
     */
    private Long uploadImageFromUrl(TencentAds tencentAds, Long accountId, String imageUrl, String description) throws Exception {
        File tempFile = null;
        try {
            // 1. 从URL下载图片到临时文件
            tempFile = downloadFileFromUrl(imageUrl);
            
            // 2. 读取文件并转Base64
            byte[] imageBytes = Files.readAllBytes(tempFile.toPath());
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            
            // 3. 计算MD5签名
            String signature = calculateMD5(imageBytes);
            
            // 4. 调用腾讯广告API上传图片
            ImagesAddResponseData response = tencentAds.images()
                .imagesAdd(
                    "UPLOAD_TYPE_BYTES",  // uploadType
                    signature,             // signature
                    accountId,             // accountId
                    null,                  // organizationId
                    null,                  // file
                    base64Image,           // bytes
                    null,                  // imageUsage
                    description,           // description
                    null,                  // resizeWidth
                    null,                  // resizeHeight
                    null                   // resizeFileSize
                );
            
            if (response == null || response.getImageId() == null) {
                throw new Exception("图片上传返回结果为空");
            }
            
            log.info("图片上传成功，imageId: {}, 宽度: {}px, 高度: {}px", 
                response.getImageId(), response.getImageWidth(), response.getImageHeight());
            
            return Long.parseLong(response.getImageId());
            
        } finally {
            // 5. 删除临时文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }
    
    /**
     * 从URL下载品牌形象并上传到腾讯广告
     * 
     * @param tencentAds 腾讯广告SDK实例
     * @param accountId 账户ID
     * @param brandImageUrl 品牌形象图片URL
     * @param brandName 品牌名称
     * @return 品牌图片ID
     * @throws Exception 上传失败
     */
    private Long uploadBrandFromUrl(TencentAds tencentAds, Long accountId, String brandImageUrl, 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 Long.parseLong(response.getImageId());
            
        } finally {
            // 3. 删除临时文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.delete();
            }
        }
    }
    
    /**
     * 从URL下载文件到临时文件
     * 
     * @param fileUrl 文件URL
     * @return 临时文件
     * @throws Exception 下载失败
     */
    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();
            }
        }
    }
    
    /**
     * 获取文件后缀名
     * 
     * @param fileUrl 文件URL
     * @return 文件后缀名（包含点号，如：.jpg）
     */
    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 ".jpg"; // 默认后缀
    }
    
    /**
     * 计算字节数组的MD5签名
     * 
     * @param bytes 字节数组
     * @return MD5签名（32位小写字符串）
     * @throws Exception 计算失败
     */
    private String calculateMD5(byte[] bytes) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(bytes);
        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;
    }
}
