package com.fs.app.facade;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.fs.newAdv.integration.adapter.IAdvertiserAdapter;
import com.fs.newAdv.integration.client.IApiClient;
import com.fs.newAdv.integration.factory.AdvertiserHandlerFactory;
import com.fs.common.utils.RedisUtil;
import com.fs.common.utils.SnowflakeUtil;
import com.fs.newAdv.domain.*;
import com.fs.newAdv.enums.AdvertiserTypeEnum;
import com.fs.newAdv.enums.SystemEventTypeEnum;
import com.fs.newAdv.mapper.ConversionLogMapper;
import com.fs.newAdv.mapper.ConversionTargetMapper;
import com.fs.newAdv.service.ICallbackAccountService;
import com.fs.newAdv.service.ILeadService;
import com.fs.newAdv.service.IPromotionAccountService;
import com.fs.newAdv.service.ISiteService;
import com.fs.newAdv.vo.ConversionEventVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 转化回传服务实现类
 *
 * @author zhangqin
 * @date 2025-11-03
 */
@Slf4j
@Service
public class ConversionServiceImpl implements IConversionService {

    @Autowired
    private ISiteService siteService;
    @Autowired
    private ICallbackAccountService callbackAccountService;
    @Autowired
    private IPromotionAccountService promotionAccountService;


    @Autowired
    private ConversionLogMapper conversionLogMapper;

    @Autowired
    private ConversionTargetMapper conversionTargetMapper;

    @Autowired
    private AdvertiserHandlerFactory advertiserHandlerFactory;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ILeadService leadService;

    @Override
    public boolean reportTrackingToAdvertiser(SystemEventTypeEnum systemEventTypeEnum, String traceId) {
        // 线索信息
        Lead lead = leadService.getByTraceId(traceId);
        // 站点信息
        Site site = siteService.getById(lead.getSiteId());
        if (site == null) {
            log.error("站点不存在：{}", site);
            return false;
        }
        // 查询回传信息
        CallbackAccount callbackAccount = callbackAccountService.getById(site.getCallbackAccountId());
        // 回传事件
        List<ConversionEventVo> conversionEventVo = callbackAccount.getConversionEventVo();
        if (CollUtil.isEmpty(conversionEventVo)) {
            log.error("回传事件不存在： {}", traceId);
            return false;
        }

        ConversionEventVo advertiserEventType = conversionEventVo.stream()
                .filter(item -> item.getSystemEventType().equals(systemEventTypeEnum.getCode()))
                .findFirst()
                .orElse(null);

        if (ObjectUtil.isEmpty(advertiserEventType)) {
            log.error("回传事件未匹配： {}", traceId);
            return false;
        }

        // 查询广告商账号
        PromotionAccount promotionAccount = promotionAccountService.getById(site.getPromotionAccountId());
        if (promotionAccount == null) {
            log.error("回传账号不存在：{}", site.getPromotionAccountId());
            return false;
        }

        Map<String, Object> params = JSONUtil.toBean(lead.getLandingPageRawParams(), Map.class);
        // 构建回传参数
        Map<String, Object> conversionData = new HashMap<>();
        // ------------------------------通用参数----------
        conversionData.put("adAccountId", callbackAccount.getAdAccountId());
        conversionData.put("appId", callbackAccount.getAppId());
        conversionData.put("appSecret", callbackAccount.getAppSecret());
        conversionData.put("accessToken", callbackAccount.getAccessToken());
        conversionData.put("ip", lead.getIp());
        conversionData.put("scr_id", callbackAccount.getScrId());
        conversionData.put("traceId", traceId);
        conversionData.put("eventType", advertiserEventType.getAdvertiserEventType());
        conversionData.put("timestamp", System.currentTimeMillis() / 1000);
        conversionData.put("viewUrl", lead.getViewUrl());

        // 添加平台适应参数
        IAdvertiserAdapter adapter = advertiserHandlerFactory.getAdapter(AdvertiserTypeEnum.getByCode(callbackAccount.getAdvertiserId()));
        adapter.uploadConversionData(conversionData, params);


        // 调用API回传
        IApiClient apiClient = advertiserHandlerFactory.getApiClient(AdvertiserTypeEnum.getByCode(site.getAdvertiserId()));
        boolean b = apiClient.reportConversion(conversionData);

        // 保存转化日志（待回传状态）
        ConversionLog conversionLog = saveConversionLog(
                site.getCallbackAccountId(),
                site.getId(), site.getAdvertiserId(), site.getAdvertiserName(),
                advertiserEventType, traceId, conversionData, b);
        return b;
    }


    /**
     * 构建巨量引擎转化数据
     */
    private Map<String, Object> buildOceanEngineConversionData(
            String clickId, String eventType, Double value) {

  /*      Map<String, Object> data = new HashMap<>();
        data.put("clickId", clickId);
        data.put("eventType", mapEventType(eventType));

        if (value != null && value > 0) {
            data.put("value", value);
        }*/

        return null;
    }

    /**
     * 保存转化日志
     */
    private ConversionLog saveConversionLog(Long callbackAccountId,Long siteId, Long advertiserId,
                                            String advertiserName, ConversionEventVo eventType,
                                            String clickId,
                                            Map<String, Object> conversionData,
                                            boolean status) {
        ConversionLog log = new ConversionLog();
        log.setId(SnowflakeUtil.nextId());
        log.setCallbackAccountId(callbackAccountId);
        log.setSiteId(siteId);
        log.setAdvertiserId(advertiserId);
        log.setAdvertiserName(advertiserName);
        log.setSysConversionEvent(eventType.getSystemEventTypeName());
        log.setAdvConversionEvent(eventType.getAdvertiserEventName());
        log.setCallbackParams(JSONUtil.toJsonStr(conversionData));
        log.setCallbackStatus(status ? 1 : 2);
        log.setRetryCount(0);
        log.setTraceId(clickId);
        log.setCreateTime(LocalDateTime.now());
        conversionLogMapper.insert(log);
        return log;
    }
}

