package com.ycwl.basic.service.pc.helper;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

import static com.ycwl.basic.constant.FaceConstant.*;

/**
 * 人脸识别指标记录器
 * 负责记录人脸识别相关的计数指标到Redis
 *
 * @author longbinbin
 * @date 2025-01-31
 */
@Slf4j
@Component
public class FaceMetricsRecorder {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 记录人脸识别次数到Redis
     * 设置2天过期时间
     *
     * @param faceId 人脸ID
     */
    public void recordRecognitionCount(Long faceId) {
        if (faceId == null) {
            return;
        }

        try {
            String redisKey = FACE_RECOGNITION_COUNT_PFX + faceId;

            // 使用Redis原子操作INCR增加计数
            Long count = redisTemplate.opsForValue().increment(redisKey);

            // 设置2天过期时间(48小时)
            redisTemplate.expire(redisKey, 2, TimeUnit.DAYS);

            log.debug("人脸识别计数更新:faceId={}, count={}", faceId, count);

        } catch (Exception e) {
            // 计数失败不应影响主要业务逻辑,只记录错误日志
            log.error("记录人脸识别次数失败:faceId={}", faceId, e);
        }
    }

    /**
     * 记录自定义人脸匹配次数到Redis
     * 设置2天过期时间
     *
     * @param faceId 人脸ID
     */
    public void recordCustomMatchCount(Long faceId) {
        if (faceId == null) {
            return;
        }

        try {
            String redisKey = FACE_CUSTOM_MATCH_COUNT_PFX + faceId;

            Long count = redisTemplate.opsForValue().increment(redisKey);
            redisTemplate.expire(redisKey, 2, TimeUnit.DAYS);

            log.debug("自定义人脸匹配计数更新:faceId={}, count={}", faceId, count);
        } catch (Exception e) {
            log.error("记录自定义人脸匹配次数失败:faceId={}", faceId, e);
        }
    }

    /**
     * 记录低阈值检测的人脸ID到Redis
     * 设置2天过期时间
     *
     * @param faceId 人脸ID
     */
    public void recordLowThreshold(Long faceId) {
        if (faceId == null) {
            return;
        }

        try {
            String redisKey = FACE_LOW_THRESHOLD_PFX + faceId;

            // 设置标记,表示该人脸ID触发了低阈值检测
            redisTemplate.opsForValue().set(redisKey, "1", 2, TimeUnit.DAYS);

            log.debug("记录低阈值检测人脸:faceId={}", faceId);

        } catch (Exception e) {
            // 记录失败不应影响主要业务逻辑,只记录错误日志
            log.error("记录低阈值检测人脸失败:faceId={}", faceId, e);
        }
    }

    /**
     * 获取人脸识别次数
     *
     * @param faceId 人脸ID
     * @return 识别次数
     */
    public long getRecognitionCount(Long faceId) {
        if (faceId == null) {
            return 0L;
        }

        try {
            String countKey = FACE_RECOGNITION_COUNT_PFX + faceId;
            String countStr = redisTemplate.opsForValue().get(countKey);
            if (countStr != null) {
                return Long.parseLong(countStr);
            }
        } catch (Exception e) {
            log.warn("获取识别次数失败:faceId={}", faceId, e);
        }

        return 0L;
    }

    /**
     * 获取自定义匹配次数
     *
     * @param faceId 人脸ID
     * @return 自定义匹配次数
     */
    public long getCustomMatchCount(Long faceId) {
        if (faceId == null) {
            return 0L;
        }

        try {
            String customMatchKey = FACE_CUSTOM_MATCH_COUNT_PFX + faceId;
            String customMatchCountStr = redisTemplate.opsForValue().get(customMatchKey);
            if (customMatchCountStr != null) {
                return Long.parseLong(customMatchCountStr);
            }
        } catch (Exception e) {
            log.warn("获取自定义匹配次数失败:faceId={}", faceId, e);
        }

        return 0L;
    }

    /**
     * 检查是否触发过低阈值检测
     *
     * @param faceId 人脸ID
     * @return 是否触发过低阈值检测
     */
    public boolean hasLowThreshold(Long faceId) {
        if (faceId == null) {
            return false;
        }

        try {
            String lowThresholdKey = FACE_LOW_THRESHOLD_PFX + faceId;
            return Boolean.TRUE.equals(redisTemplate.hasKey(lowThresholdKey));
        } catch (Exception e) {
            log.warn("检查低阈值状态失败:faceId={}", faceId, e);
            return false;
        }
    }
}
