package com.ycwl.basic.repository;

import com.fasterxml.jackson.core.type.TypeReference;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
import com.ycwl.basic.utils.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class MemberRelationRepository {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private SourceMapper sourceMapper;

    public static final String MEMBER_RELATION_BY_FACE_CACHE_KEY = "member_relation:face:%d:v";
    public static final String MEMBER_RELATION_BY_FACE_TEMPLATE_CACHE_KEY = "member_relation:face:%d:v:template:%d";
    public static final String MEMBER_SOURCE_BY_FACE_TYPE_CACHE_KEY = "member_relation:face:%d:s:type:%d";

    public List<MemberVideoEntity> listRelationByFace(Long faceId) {
        String cacheKey = String.format(MEMBER_RELATION_BY_FACE_CACHE_KEY, faceId);

        if (redisTemplate.hasKey(cacheKey)) {
            String cacheValue = redisTemplate.opsForValue().get(cacheKey);
            return JacksonUtil.fromJson(cacheValue, new TypeReference<List<MemberVideoEntity>>() {});
        }

        List<MemberVideoEntity> result = videoMapper.listRelationByFace(faceId);
        if (result != null) {
            redisTemplate.opsForValue().set(cacheKey, JacksonUtil.toJson(result), 1, TimeUnit.HOURS);
        }

        return result;
    }

    public List<MemberVideoEntity> listRelationByFaceAndTemplate(Long faceId, Long templateId) {
        String cacheKey = String.format(MEMBER_RELATION_BY_FACE_TEMPLATE_CACHE_KEY, faceId, templateId);

        if (redisTemplate.hasKey(cacheKey)) {
            String cacheValue = redisTemplate.opsForValue().get(cacheKey);
            return JacksonUtil.fromJson(cacheValue, new TypeReference<List<MemberVideoEntity>>() {});
        }

        List<MemberVideoEntity> result = videoMapper.listRelationByFaceAndTemplate(faceId, templateId);
        if (result != null) {
            redisTemplate.opsForValue().set(cacheKey, JacksonUtil.toJson(result), 1, TimeUnit.HOURS);
        }

        return result;
    }

    public List<MemberSourceEntity> listSourceByFaceRelation(Long faceId, Integer type) {
        String cacheKey = String.format(MEMBER_SOURCE_BY_FACE_TYPE_CACHE_KEY, faceId, type);

        if (redisTemplate.hasKey(cacheKey)) {
            String cacheValue = redisTemplate.opsForValue().get(cacheKey);
            return JacksonUtil.fromJson(cacheValue, new TypeReference<List<MemberSourceEntity>>() {});
        }

        List<MemberSourceEntity> result = sourceMapper.listByFaceRelation(faceId, type);
        if (result != null) {
            redisTemplate.opsForValue().set(cacheKey, JacksonUtil.toJson(result), 1, TimeUnit.HOURS);
        }

        return result;
    }

    public void clearCacheByFace(Long faceId) {
        String pattern = "member_relation:face:" + faceId + ":*";
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    public void clearVCacheByFace(Long faceId) {
        String pattern = "member_relation:face:" + faceId + ":v:*";
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    public void clearSCacheByFace(Long faceId) {
        String pattern = "member_relation:face:" + faceId + ":s:*";
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

    public void clearAllCache() {
        String pattern = "member_relation:*";
        Set<String> keys = redisTemplate.keys(pattern);
        if (keys != null && !keys.isEmpty()) {
            redisTemplate.delete(keys);
        }
    }

}
