package com.fs.company.service.impl;

import com.fs.common.core.redis.RedisCache;
import com.fs.common.core.text.Convert;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.StringUtils;
import com.fs.company.domain.CompanyConfig;
import com.fs.company.mapper.CompanyConfigMapper;
import com.fs.company.service.ICompanyConfigService;
import com.fs.system.domain.SysConfig;
import org.apache.http.util.Asserts;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

import static com.fs.common.utils.DictUtils.getCacheKey;

/**
 * 参数配置Service业务层处理
 *
 * @author fs
 * @date 2021-05-25
 */
@Service
public class CompanyConfigServiceImpl implements ICompanyConfigService
{
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CompanyConfigMapper companyConfigMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate; // 注入RedisTemplate
    private static final String REDIS_KEY_PREFIX = "red_packet_config:";
    private static final long CACHE_TIMEOUT = 24 * 60 * 60;

    /**
     * 查询参数配置
     *
     * @param configId 参数配置ID
     * @return 参数配置
     */
    @Override
    public CompanyConfig selectCompanyConfigById(Integer configId)
    {
        return companyConfigMapper.selectCompanyConfigById(configId);
    }

    /**
     * 查询参数配置列表
     *
     * @param companyConfig 参数配置
     * @return 参数配置
     */
    @Override
    public List<CompanyConfig> selectCompanyConfigList(CompanyConfig companyConfig)
    {
        return companyConfigMapper.selectCompanyConfigList(companyConfig);
    }

    /**
     * 新增参数配置
     *
     * @param companyConfig 参数配置
     * @return 结果
     */
    @Override
    public int insertCompanyConfig(CompanyConfig companyConfig)
    {
        companyConfig.setCreateTime(DateUtils.getNowDate());
        return companyConfigMapper.insertCompanyConfig(companyConfig);
    }

    /**
     * 修改参数配置
     *
     * @param companyConfig 参数配置
     * @return 结果
     */
    @Override
    public int updateCompanyConfig(CompanyConfig companyConfig)
    {
        companyConfig.setUpdateTime(DateUtils.getNowDate());
        return companyConfigMapper.updateCompanyConfig(companyConfig);
    }

    /**
     * 批量删除参数配置
     *
     * @param configIds 需要删除的参数配置ID
     * @return 结果
     */
    @Override
    public int deleteCompanyConfigByIds(Integer[] configIds)
    {
        return companyConfigMapper.deleteCompanyConfigByIds(configIds);
    }

    /**
     * 删除参数配置信息
     *
     * @param configId 参数配置ID
     * @return 结果
     */
    @Override
    public int deleteCompanyConfigById(Integer configId)
    {
        return companyConfigMapper.deleteCompanyConfigById(configId);
    }

    @Override
    public CompanyConfig selectCompanyConfigByKey(Long companyId, String key) {
        return companyConfigMapper.selectCompanyConfigByKey(companyId,key);
    }

    @Override
    public String selectCompanyConfigByKey(String key) {
        return companyConfigMapper.selectConfigByKey(key);
    }

    @Override
    public String selectConfigByKey(String configKey) {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
        if (StringUtils.isNotEmpty(configValue))
        {
            return configValue;
        }
        SysConfig retConfig = companyConfigMapper.selectConfig(configKey);
        if (StringUtils.isNotNull(retConfig))
        {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StringUtils.EMPTY;
    }

    @Override
    public CompanyConfig selectCompanyConfigByServerKey(String key) {
        return companyConfigMapper.selectCompanyConfigByServerKey(key);
    }

    @Override
    public String selectRedPacketConfigByKey(Long companyId) {
        Asserts.notNull(companyId,"公司id不能为空！");
        String redisKey = REDIS_KEY_PREFIX + companyId;
        String cachedConfig = redisTemplate.opsForValue().get(redisKey);
        if (cachedConfig != null) {
            return cachedConfig;
        }
        synchronized (getSynchronizationObject(companyId)) {
            cachedConfig = redisTemplate.opsForValue().get(redisKey);

            if (cachedConfig != null) {
                return cachedConfig;
            }
            String configFromDb = companyConfigMapper.selectRedPacketConfigByKey(companyId);
            if (configFromDb != null) {
                redisTemplate.opsForValue().set(redisKey, configFromDb, CACHE_TIMEOUT, TimeUnit.SECONDS);
            } else {
                redisTemplate.opsForValue().set(redisKey, "", 5 * 60, TimeUnit.SECONDS);
            }
            return configFromDb;
        }
    }

    private static final ConcurrentHashMap<Long, Object> LOCKS = new ConcurrentHashMap<>();
    private static Object getSynchronizationObject(Long companyId) {
        return LOCKS.computeIfAbsent(companyId, k -> new Object());
    }
}
