package com.qs.mp.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qs.mp.admin.domain.TicketBox;
import com.qs.mp.admin.mapper.TicketBoxMapper;
import com.qs.mp.admin.service.ITicketBoxSerialService;
import com.qs.mp.common.annotation.Log;
import com.qs.mp.common.core.redis.RedisCache;
import com.qs.mp.common.enums.TicketTypeEnum;
import com.qs.mp.common.utils.LogUtil;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * @author zhongcp
 * @Date 2022/3/11
 */
@Service
public class TicketBoxSerialServiceImpl implements ITicketBoxSerialService {

  protected final Logger logger = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private RedisCache redisCache;

  @Autowired
  private RedisTemplate redisTemplate;

  @Autowired
  private TicketBoxMapper ticketBoxMapper;

  public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy");

  @Override
  public String generateSerial(TicketTypeEnum ticketType) {
    //年份后两位
    String strYear = sdf.format(new Date());
    String prefix = strYear.substring(2);

    //如果日期前缀未过期，则序号自增
    //否则，将日期作为Key，1作为Value重置，并设置第二年0点过期
    if (redisCache.hasKey(prefix)) {
      redisTemplate.opsForValue().increment(prefix, 1);
      LogUtil.debug(logger, "缓存中存在，key:" + prefix);
    } else {
      int start = Integer.valueOf(strYear);
      List<TicketBox> ticketBoxList = ticketBoxMapper.selectList(new QueryWrapper<TicketBox>().orderByDesc("created_time").last("limit 1"));
      if (!CollectionUtils.isEmpty(ticketBoxList)) {
        String boxNo = ticketBoxList.get(0).getBoxNo();

        int year = Character.codePointAt(boxNo.substring(2, 3), 0) - 50;
        // 同一年份，做累加
        if (year == Integer.valueOf(prefix)) {
          start = Integer.valueOf(boxNo.substring(2)) + 1;
        }
      }
      redisTemplate.opsForValue().set(prefix, start);
      redisTemplate.expireAt(prefix, getNextYearDate());
      LogUtil.debug(logger, "缓存中不存在，key:{0}, start:{1}", new Object[]{prefix, start});
    }
    String str = new String(Character.toChars(Integer.parseInt(prefix) + 50));
    Object value = redisTemplate.opsForValue().get(prefix);
    LogUtil.debug(logger, "生成的年份为{0},序列号为{1}", new Object[]{str, value});

    String type = ticketType == TicketTypeEnum.ONLINE ? "S" : "X";
    return "T" + type + str + String.format("%1$05d", value);
  }

  // 获取第二年 1月 1日 00:00的时间
  private static Date getNextYearDate() {
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.MONTH, 1);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.add(Calendar.YEAR, 1);
    return calendar.getTime();
  }
}
