package com.ycwl.basic.repository;

import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.TemplateMapper;
import com.ycwl.basic.model.pc.template.entity.TemplateConfigEntity;
import com.ycwl.basic.model.pc.template.entity.TemplateEntity;
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
import com.ycwl.basic.utils.SnowFlakeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service // 临时这么用
public class TemplateRepository {
    @Autowired
    private TemplateMapper templateMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    public static final String TEMPLATE_CACHE_KEY = "template:%s";
    public static final String TEMPLATE_ID_BY_SCENIC_ID_CACHE_KEY = "template:id:byScenic:%s";
    public static final String TEMPLATE_CONFIG_CACHE_KEY = "template:%s:config";


    public List<String> getTemplatePlaceholder(Long templateId) {
        TemplateRespVO template = getTemplate(templateId);
        return template.getChildren().stream()
                .filter(item -> item.getIsPlaceholder() == 1)
                .map(TemplateRespVO::getSourceUrl)
                .collect(Collectors.toList());
    }

    public int getTemplateMinimalPlaceholderCount(Long templateId) {
        TemplateConfigEntity config = getTemplateConfig(templateId);
        if (config == null || config.getMinimalPlaceholderFill() == null) {
            return 1;
        } else {
            return config.getMinimalPlaceholderFill();
        }
    }

    public List<TemplateRespVO> getAllEnabledTemplateList() {
        List<TemplateEntity> entityList = templateMapper.listEnabled();
        if (entityList == null) {
            return Collections.emptyList();
        }
        return entityList.stream().map(entity -> getTemplate(entity.getId())).collect(Collectors.toList());
    }

    public List<TemplateRespVO> getTemplateListByScenicId(Long scenicId) {
        List<Long> idList;
        if (redisTemplate.hasKey(String.format(TEMPLATE_ID_BY_SCENIC_ID_CACHE_KEY, scenicId))) {
            idList = JSONObject.parseArray(redisTemplate.opsForValue().get(String.format(TEMPLATE_ID_BY_SCENIC_ID_CACHE_KEY, scenicId)), Long.class);
        } else {
            idList = templateMapper.listEnabledTemplateIdByScenicId(scenicId);
            redisTemplate.opsForValue().set(String.format(TEMPLATE_ID_BY_SCENIC_ID_CACHE_KEY, scenicId), JSONObject.toJSONString(idList));
        }
        if (idList == null || idList.isEmpty()) {
            return Collections.emptyList();
        }
        return idList.stream().map(this::getTemplate).collect(Collectors.toList());
    }

    public List<TemplateRespVO> getAllTemplateListByScenicId(Long scenicId) {
        List<Long> idList;
        idList = templateMapper.listAllTemplateIdByScenicId(scenicId);
        if (idList == null || idList.isEmpty()) {
            return Collections.emptyList();
        }
        return idList.stream().map(this::getTemplate).collect(Collectors.toList());
    }

    public TemplateRespVO getTemplate(Long templateId) {
        if (redisTemplate.hasKey(String.format(TEMPLATE_CACHE_KEY, templateId))) {
            return JSONObject.parseObject(redisTemplate.opsForValue().get(String.format(TEMPLATE_CACHE_KEY, templateId)), TemplateRespVO.class);
        }
        TemplateRespVO template = templateMapper.getById(templateId);
        if (template == null) {
            return null;
        }
        if (null == template.getPid() || template.getPid() == 0) {
            template.setChildren(templateMapper.getByPid(templateId));
            redisTemplate.opsForValue().set(String.format(TEMPLATE_CACHE_KEY, templateId), JSONObject.toJSONString(template));
            return template;
        } else {
            clearTemplateCache(templateId);
            return null;
        }
    }

    public TemplateConfigEntity getTemplateConfig(Long templateId) {
        if (templateId == null) {
            return new TemplateConfigEntity();
        }
        if (redisTemplate.hasKey(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId))) {
            return JSONObject.parseObject(redisTemplate.opsForValue().get(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId)), TemplateConfigEntity.class);
        }
        TemplateConfigEntity templateConfig = templateMapper.getConfig(templateId);
        if (templateConfig == null) {
            templateConfig = new TemplateConfigEntity();
            templateConfig.setId(SnowFlakeUtil.getLongId());
            templateConfig.setTemplateId(templateId);
            templateMapper.addConfig(templateConfig);
        }
        redisTemplate.opsForValue().set(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId), JSONObject.toJSONString(templateConfig));
        return templateConfig;
    }

    public boolean clearTemplateCache(Long templateId) {
        if (redisTemplate.hasKey(String.format(TEMPLATE_CACHE_KEY, templateId))) {
            TemplateRespVO template = getTemplate(templateId);
            redisTemplate.delete(String.format(TEMPLATE_ID_BY_SCENIC_ID_CACHE_KEY, template.getScenicId()));
        }
        redisTemplate.delete(String.format(TEMPLATE_CACHE_KEY, templateId));
        redisTemplate.delete(String.format(TEMPLATE_CONFIG_CACHE_KEY, templateId));
        return true;
    }
}
