package com.tzld.piaoquan.ad.engine.commons.helper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class ModelUserLayerDataHelper {
    @Autowired
    protected AlgorithmRedisHelper algRedisHelper;

    private static final String redisKey = "ad:engine:strategy:model_ctcvr_calibration";
    private static final String keyFormat = "%s:%s:%s:%s:%s:%s";
    private static final String SUM = "sum";

    private volatile static Map<String, Double> dataMap = Collections.emptyMap();

    // 服务启动时初始化数据
    @PostConstruct
    public void init() {
        Map<String, Double> map = updateDataMap();
        if (map != null) {
            dataMap = Collections.unmodifiableMap(map);
        }
    }

    // 每5分钟更新一次数据
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void scheduledUpdate() {
        Map<String, Double> map = updateDataMap();
        if (map != null) {
            dataMap = Collections.unmodifiableMap(map);
        }
    }

    public static Double getCopc(String model, String landingPageType, String targetingConversion, String layer, String profession, String customerId) {
        if (null != dataMap) {
            model = nullToSum(model);
            landingPageType = nullToSum(landingPageType);
            targetingConversion = nullToSum(targetingConversion);
            layer = nullToSum(layer);
            profession = nullToSum(profession);
            customerId = nullToSum(customerId);

            String key = String.format(keyFormat, model, landingPageType, targetingConversion, layer, profession, customerId);
            if (dataMap.containsKey(key)) {
                return dataMap.get(key);
            }
            key = String.format(keyFormat, model, landingPageType, targetingConversion, layer, profession, SUM);
            if (dataMap.containsKey(key)) {
                return dataMap.get(key);
            }
            key = String.format(keyFormat, model, landingPageType, targetingConversion, layer, SUM, SUM);
            if (dataMap.containsKey(key)) {
                return dataMap.get(key);
            }
        }
        return null;
    }

    private static String nullToSum(String value) {
        if (value == null || value.isEmpty() || "null".equalsIgnoreCase(value)) {
            return SUM;
        }
        return value;
    }

    /**
     * @return 新数据；失败返回 null，调用方保留旧 dataMap
     */
    private Map<String, Double> updateDataMap() {
        try {
            String value = algRedisHelper.get(redisKey);

            if (value == null || value.trim().isEmpty()) {
                log.warn("update model layer copc skipped: redis value is empty, keep old dataMap size={}", dataMap.size());
                return null;
            }

            Map<String, Double> newDataMap = JSON.parseObject(
                    value,
                    new TypeReference<Map<String, Double>>() {}
            );

            if (newDataMap == null) {
                log.warn("update model layer copc skipped: parsed map is null, keep old dataMap size={}", dataMap.size());
                return null;
            }

            log.info("update model layer copc success size={}", newDataMap.size());
            return newDataMap;
        } catch (Exception e) {
            log.error("update model layer copc error, keep old dataMap size={}", dataMap.size(), e);
            return null;
        }
    }
}
