package com.ycwl.basic.repository;

import com.ycwl.basic.biz.PriceBiz;
import com.ycwl.basic.pricing.service.IVoucherService;
import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.model.pc.video.resp.VideoRespVO;
import com.ycwl.basic.model.task.req.VideoInfoReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class VideoRepository {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private VideoMapper videoMapper;

    public static final String VIDEO_CACHE_KEY = "video:%s";
    public static final String VIDEO_BY_TASK_ID_CACHE_KEY = "video:task:%s";
    @Autowired
    private MemberRelationRepository memberRelationRepository;

    public VideoEntity getVideo(Long videoId) {
        if (redisTemplate.hasKey(String.format(VIDEO_CACHE_KEY, videoId))) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(VIDEO_CACHE_KEY, videoId)), VideoEntity.class);
        }
        VideoEntity video = videoMapper.getEntity(videoId);
        if (video != null) {
            redisTemplate.opsForValue().set(String.format(VIDEO_CACHE_KEY, videoId), JacksonUtil.toJSONString(video), 12, TimeUnit.HOURS);
            redisTemplate.opsForValue().set(String.format(VIDEO_BY_TASK_ID_CACHE_KEY, video.getTaskId()), JacksonUtil.toJSONString(video), 12, TimeUnit.HOURS);
        }
        return video;
    }

    public VideoEntity getVideoByTaskId(Long taskId) {
        if (redisTemplate.hasKey(String.format(VIDEO_BY_TASK_ID_CACHE_KEY, taskId))) {
            return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(VIDEO_BY_TASK_ID_CACHE_KEY, taskId)), VideoEntity.class);
        }
        VideoEntity video = videoMapper.findByTaskId(taskId);
        if (video != null) {
            redisTemplate.opsForValue().set(String.format(VIDEO_BY_TASK_ID_CACHE_KEY, taskId), JacksonUtil.toJSONString(video), 12, TimeUnit.HOURS);
            redisTemplate.opsForValue().set(String.format(VIDEO_CACHE_KEY, video.getId()), JacksonUtil.toJSONString(video), 12, TimeUnit.HOURS);
        }
        return video;
    }

    public void updateMeta(Long videoId, VideoInfoReq req) {
        VideoRespVO video = videoMapper.getById(videoId);
        if (video.getDuration() != null) {
            if (video.getDuration().subtract(req.getDuration()).abs().compareTo(BigDecimal.ONE) <= 0) {
                return;
            }
        }
        VideoEntity update = new VideoEntity();
        update.setId(videoId);
        update.setHeight(req.getHeight());
        update.setWidth(req.getWidth());
        update.setDuration(req.getDuration());
        videoMapper.updateMeta(update);
        clearVideoCache(videoId);
    }

    public void setUserIsBuyItem(Long memberId, Long videoId, Long orderId) {
        MemberVideoEntity memberVideo = new MemberVideoEntity();
        memberVideo.setVideoId(videoId);
        memberVideo.setMemberId(memberId);
        memberVideo.setIsBuy(1);
        memberVideo.setOrderId(orderId);
        videoMapper.updateRelation(memberVideo);

        // 清理视频关系缓存
        MemberVideoEntity existingVideo = videoMapper.queryUserVideo(memberId, videoId);
        if (existingVideo != null && existingVideo.getFaceId() != null) {
            memberRelationRepository.clearVCacheByFace(existingVideo.getFaceId());
        }
    }

    public void setUserNotBuyItem(Long memberId, Long videoId) {
        MemberVideoEntity memberVideo = new MemberVideoEntity();
        memberVideo.setVideoId(videoId);
        memberVideo.setMemberId(memberId);
        memberVideo.setIsBuy(0);
        memberVideo.setOrderId(null);
        videoMapper.updateRelation(memberVideo);

        // 清理视频关系缓存
        MemberVideoEntity existingVideo = videoMapper.queryUserVideo(memberId, videoId);
        if (existingVideo != null && existingVideo.getFaceId() != null) {
            memberRelationRepository.clearVCacheByFace(existingVideo.getFaceId());
        }
    }

    public boolean clearVideoCache(Long videoId) {
        if (redisTemplate.hasKey(String.format(VIDEO_CACHE_KEY, videoId))) {
            VideoEntity video = getVideo(videoId);
            redisTemplate.delete(String.format(VIDEO_CACHE_KEY, videoId));
            redisTemplate.delete(String.format(VIDEO_BY_TASK_ID_CACHE_KEY, video.getTaskId()));
        }
        return true;
    }

    public void setUserIsBuyTemplate(Long memberId, Long templateId, Long orderId, Long faceId) {
        List<MemberVideoEntity> videoEntities = memberRelationRepository.listRelationByFace(faceId);
        for (MemberVideoEntity videoEntity : videoEntities) {
            if (videoEntity.getTemplateId() != null && videoEntity.getTemplateId().equals(templateId)) {
                MemberVideoEntity memberVideo = new MemberVideoEntity();
                memberVideo.setVideoId(videoEntity.getVideoId());
                memberVideo.setMemberId(memberId);
                memberVideo.setIsBuy(1);
                memberVideo.setOrderId(orderId);
                videoMapper.updateRelation(memberVideo);

                // 清理视频关系缓存
                MemberVideoEntity existingVideo = videoMapper.queryUserVideo(memberId, videoEntity.getVideoId());
                if (existingVideo != null && existingVideo.getFaceId() != null) {
                    memberRelationRepository.clearVCacheByFace(existingVideo.getFaceId());
                }
            }
        }


    }

    /**
     * 通过faceId和templateId（可选）查询最新的视频记录
     * @param faceId 人脸ID
     * @param templateId 模板ID（可选）
     * @return 最新的视频记录
     */
    public VideoRespVO queryLatestByFaceIdAndTemplateId(Long faceId, Long templateId) {
        return videoMapper.queryLatestByFaceIdAndTemplateId(faceId, templateId);
    }
}
