package com.yolo.keyboard.service.themes;

import cn.hutool.core.collection.CollUtil;
import com.yolo.keyboard.controller.admin.themes.vo.KeyboardThemesPageReqVO;
import com.yolo.keyboard.controller.admin.themes.vo.KeyboardThemesSaveReqVO;
import com.yolo.keyboard.dal.dataobject.themes.KeyboardThemesDO;
import com.yolo.keyboard.dal.mysql.themes.KeyboardThemesMapper;
import com.yolo.keyboard.framework.common.pojo.PageResult;
import com.yolo.keyboard.framework.common.util.object.BeanUtils;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.yolo.keyboard.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yolo.keyboard.module.infra.enums.ErrorCodeConstants.THEMES_NOT_EXISTS;

/**
 * 键盘皮肤 Service 实现类
 *
 * @author ziin
 */
@Service
@Validated
public class KeyboardThemesServiceImpl implements KeyboardThemesService {

    private static final String THEME_STYLE_KEY_PREFIX = "theme:style:";
    private static final String THEME_STYLE_ALL_KEY = "theme:style:all";
    private static final Long ALL_STYLE_ID = 9999L;

    @Resource
    private KeyboardThemesMapper themesMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Long createThemes(KeyboardThemesSaveReqVO createReqVO) {
        // 插入
        KeyboardThemesDO themes = BeanUtils.toBean(createReqVO, KeyboardThemesDO.class);
        themesMapper.insert(themes);

        // 同步更新 Redis 缓存
        refreshThemeStyleCache(themes.getThemeStyle());

        // 返回
        return themes.getId();
    }

    @Override
    public void updateThemes(KeyboardThemesSaveReqVO updateReqVO) {
        // 校验存在
        KeyboardThemesDO oldTheme = themesMapper.selectById(updateReqVO.getId());
        validateThemesExists(updateReqVO.getId());

        // 更新
        KeyboardThemesDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardThemesDO.class);
        themesMapper.updateById(updateObj);

        // 同步更新 Redis 缓存（如果风格变更，需要刷新新旧两个风格的缓存）
        refreshThemeStyleCache(updateReqVO.getThemeStyle());
        if (oldTheme != null && oldTheme.getThemeStyle() != null
                && !oldTheme.getThemeStyle().equals(updateReqVO.getThemeStyle())) {
            refreshThemeStyleCache(oldTheme.getThemeStyle());
        }
    }

    @Override
    public void deleteThemes(Long id) {
        // 校验存在
        KeyboardThemesDO theme = themesMapper.selectById(id);
        validateThemesExists(id);

        // 删除
        themesMapper.deleteById(id);

        // 同步更新 Redis 缓存
        if (theme != null && theme.getThemeStyle() != null) {
            refreshThemeStyleCache(theme.getThemeStyle());
        }
    }

    @Override
    public void deleteThemesListByIds(List<Long> ids) {
        // 获取要删除的主题列表，记录其风格
        List<KeyboardThemesDO> themes = themesMapper.selectBatchIds(ids);
        Set<Long> styleIds = new HashSet<>();
        if (CollUtil.isNotEmpty(themes)) {
            for (KeyboardThemesDO theme : themes) {
                if (theme.getThemeStyle() != null) {
                    styleIds.add(theme.getThemeStyle());
                }
            }
        }

        // 删除
        themesMapper.deleteByIds(ids);

        // 同步更新 Redis 缓存
        for (Long styleId : styleIds) {
            refreshThemeStyleCache(styleId);
        }
    }


    private void validateThemesExists(Long id) {
        if (themesMapper.selectById(id) == null) {
            throw exception(THEMES_NOT_EXISTS);
        }
    }

    @Override
    public KeyboardThemesDO getThemes(Long id) {
        return themesMapper.selectById(id);
    }

    @Override
    public PageResult<KeyboardThemesDO> getThemesPage(KeyboardThemesPageReqVO pageReqVO) {
        return themesMapper.selectPage(pageReqVO);
    }

    /**
     * 刷新主题风格缓存
     *
     * @param styleId 风格ID
     */
    private void refreshThemeStyleCache(Long styleId) {
        if (styleId == null) {
            return;
        }

        // 1. 刷新指定风格的缓存
        String styleKey = THEME_STYLE_KEY_PREFIX + styleId;
        List<KeyboardThemesDO> themesByStyle = themesMapper.selectList(KeyboardThemesDO::getThemeStyle, styleId);
        if (CollUtil.isNotEmpty(themesByStyle)) {
            redisTemplate.opsForValue().set(styleKey, themesByStyle);
        } else {
            redisTemplate.delete(styleKey);
        }

        // 2. 刷新全部主题缓存（theme:style:all）
        List<KeyboardThemesDO> allThemes = themesMapper.selectList();
        if (CollUtil.isNotEmpty(allThemes)) {
            redisTemplate.opsForValue().set(THEME_STYLE_ALL_KEY, allThemes);
        } else {
            redisTemplate.delete(THEME_STYLE_ALL_KEY);
        }
    }

}