package com.hdkj.lt.utils.cache;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import org.apache.commons.compress.utils.Lists;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {

    @Resource
    RedisTemplate stringRedisTemplate;


    private static final String PREFIX = "WT";
    private static final String WORK_ORDER_INIT = "0000";
    private static final String EQUIPMENT_INIT = "0000";

    public static final String CHANGE_MANAGER_CODE = "CHANGE_MANAGER_CODE:";

    public synchronized List<String> generateQuotationNumber(int count){
        StringBuilder buffer = new StringBuilder();
        buffer.append(PREFIX);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        buffer.append(format.format(new Date()));
        String incKey = buffer.toString();
        String no = incr(incKey,1,WORK_ORDER_INIT);
        buffer.append(no);
        List<String> ids = Lists.newArrayList();
        buffer.append("-");
        String s = buffer.toString();
        for (int i = 0; i < count; i++) {
            String incr = incr(s, 1,EQUIPMENT_INIT);
            ids.add(s+incr);
        }
        return ids;
    }

    private String incr(String incKey, int time, String workOrderInit) {
        RedisAtomicLong atomicLong = new RedisAtomicLong(incKey, stringRedisTemplate.getConnectionFactory());
        //对于该key值进行自增1操作
        Long increment = atomicLong.getAndIncrement();
        if ((null == increment || increment.longValue() == 0) && time >0){
            atomicLong.expire(time, TimeUnit.DAYS);
        }
        if (Objects.nonNull(increment) && increment > 9999){
            increment = 1L;
        }else if (Objects.nonNull(increment) && increment >= 0){
            increment = increment +1;
        }
        DecimalFormat df = new DecimalFormat(workOrderInit);
        return df.format(increment);
    }

    public Long incr(String incKey, Long time,TimeUnit unit) {
        ValueOperations valueOperations = stringRedisTemplate.opsForValue();
        Long increment = valueOperations.increment(incKey);
        if (increment==null){
            valueOperations.setIfAbsent(incKey, "0", time, unit);
            return this.incr(incKey,time,unit);
        }
        if (increment==1){
            stringRedisTemplate.expire(incKey,time,unit);
        }
        return increment;
    }

    public Long incr(String incKey) {
        Date date = new Date();
        DateTime dateTime = DateUtil.endOfDay(date);
        long between = dateTime.between(date, DateUnit.MS);
        return this.incr(incKey,between,TimeUnit.MILLISECONDS);
    }

    //============================String=============================
    /**
     * 普通缓存获取
     * @param key 键
     * @return 值
     */
    public Object get(String key){
        return key==null?null:stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 指定缓存失效时间
     * @param key 键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key,long time){
        try {
            if(time>0){
                stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key){
        return stringRedisTemplate.getExpire(key,TimeUnit.SECONDS);
    }

    /**
     * 普通缓存放入
     * @param key 键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key,Object value) {
        try {
            stringRedisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     * @param key 键
     * @param value 值
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key,Object value,long time){
        try {
            if(time>0){
                stringRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            }else{
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 模糊查询获取key值
     * @param pattern
     * @return
     */
    public Set<String> keys(String pattern){
        return stringRedisTemplate.keys(pattern);
    }

    /**
     * 删除缓存
     * @param key
     * @return
     */
    public Boolean del(String key) {
        return stringRedisTemplate.delete(key);
    }

    //=========BoundListOperations 用法 End============
}
