package com.moka.gdtauto.service;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.moka.gdtauto.client.TencentAdsApiClientFactory;
import com.moka.gdtauto.common.Constant;
import com.moka.gdtauto.entity.TencentAssetFiction;
import com.moka.gdtauto.mapper.TencentAssetFictionMapper;
import com.tencent.ads.exception.TencentAdsResponseException;
import com.tencent.ads.exception.TencentAdsSDKException;
import com.tencent.ads.model.v3.FilteringStruct;
import com.tencent.ads.model.v3.MarketingTargetAssetsGetResponseData;
import com.tencent.ads.v3.TencentAds;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 腾讯广告小说资产服务
 *
 * @author mokamvp
 * @since 2026-03-11
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TencentAssetFictionService extends ServiceImpl<TencentAssetFictionMapper, TencentAssetFiction> {

    private final TencentAssetFictionMapper tencentAssetFictionMapper;
    private final TencentAdsApiClientFactory clientFactory;
    private final TencentAdsAuthService tencentAdsAuthService;

    /**
     * 获取小说资产列表
     * https://developers.e.qq.com/v3.0/docs/api/marketing_target_assets/get
     *
     * @param orgAccountId 组织账户ID
     * @param jobNumber 工号
     * @param accountId 推广账号ID
     * @param filtering 过滤条件
     * @param page 页码
     * @param pageSize 每页大小
     * @return 小说资产列表响应数据
     * @throws TencentAdsResponseException API响应异常
     * @throws TencentAdsSDKException SDK异常
     */
    public MarketingTargetAssetsGetResponseData getMarketingAssets(
            Long orgAccountId,
            String jobNumber,
            Long accountId,
            List<FilteringStruct> filtering,
            Long page,
            Long pageSize) throws TencentAdsResponseException, TencentAdsSDKException, Exception {

        log.info("获取小说资产列表, accountId: {}, page: {}, pageSize: {}", accountId, page, pageSize);

        TencentAds tencentAds = clientFactory.getTencentAds(jobNumber, Constant.MAIN_ORG_ACCOUNT_ID);

        MarketingTargetAssetsGetResponseData response = tencentAds.marketingTargetAssets()
            .marketingTargetAssetsGet(
                "MARKETING_TARGET_TYPE_FICTION",  // marketing_target_type
                accountId,
                filtering,
                page,
                pageSize,
                null,  // organization_id
                null   // fields
            );

        log.info("获取小说资产列表成功, 总数: {}",
            response.getPageInfo() != null ? response.getPageInfo().getTotalNumber() : 0);

        return response;
    }

    /**
     * 同步小说资产数据到数据库
     * 每次查询后立即保存，最多同步2000条
     *
     * @param orgAccountId 组织账户ID
     * @param jobNumber 工号
     * @param accountId 推广账号ID
     * @return 同步的资产数量
     * @throws Exception 异常
     */
    @Transactional(rollbackFor = Exception.class)
    public int syncMarketingAssets(String jobNumber, Long orgAccountId, Long accountId) throws Exception {
        log.info("开始同步小说资产, jobNumber: {}, orgAccountId: {}, accountId: {}", jobNumber, orgAccountId, accountId);

        int totalCount = 0; // 总同步数量
        int maxRecords = 2000; // 最多同步2000条
        Long page = 1L;
        Long pageSize = 100L;

        while (totalCount < maxRecords) {
            MarketingTargetAssetsGetResponseData response = getMarketingAssets(
                Constant.MAIN_ORG_ACCOUNT_ID, jobNumber, accountId, null, page, pageSize);

            if (response == null || CollectionUtils.isEmpty(response.getList())) {
                log.info("没有更多数据，结束同步");
                break;
            }

            // 转换为实体对象
            List<TencentAssetFiction> assets = convertToEntities(response);
            assets.forEach(asset -> {
                asset.setJobNumber(jobNumber);
                asset.setAccountId(accountId);
            });

            // 立即保存当前批次数据
            if (!CollectionUtils.isEmpty(assets)) {
                int count = tencentAssetFictionMapper.batchInsertOrUpdate(assets);
                totalCount += count;
                log.info("第{}页数据保存成功，本次影响行数: {}，累计: {}", page, count, totalCount);
            }

            // 判断是否达到上限
            if (totalCount >= maxRecords) {
                log.info("已达到最大同步数量{}，结束同步", maxRecords);
                break;
            }

            // 判断是否还有下一页
            if (response.getPageInfo() == null ||
                page >= response.getPageInfo().getTotalPage()) {
                log.info("已是最后一页，结束同步");
                break;
            }

            page++;
        }

        log.info("同步小说资产完成，总影响行数: {}", totalCount);
        return totalCount;
    }

    /**
     * 转换API响应为实体对象列表
     *
     * @param response API响应数据
     * @return 实体对象列表
     */
    private List<TencentAssetFiction> convertToEntities(MarketingTargetAssetsGetResponseData response) {
        List<TencentAssetFiction> result = new ArrayList<>();

        if (response == null || CollectionUtils.isEmpty(response.getList())) {
            return result;
        }

        for (var item : response.getList()) {
            TencentAssetFiction entity = new TencentAssetFiction();
            entity.setMarketingAssetId(item.getMarketingAssetId());
            entity.setMarketingAssetName(item.getMarketingAssetName());
            entity.setMarketingAssetType(item.getMarketingAssetType() != null ?
                item.getMarketingAssetType().toString() : null);
            entity.setCreatedTime(item.getCreatedTime());
            // SDK中MarketingAssetStruct没有isDeleted字段，默认设置为false
            entity.setIsDeleted(false);

            // 将properties转为JSON字符串
            if (item.getProperties() != null && !item.getProperties().isEmpty()) {
                try {
                    entity.setProperties(JSON.toJSONString(item.getProperties()));
                } catch (Exception e) {
                    log.warn("转换properties失败: {}", e.getMessage());
                }
            }

            result.add(entity);
        }

        return result;
    }
}
