package com.red.circle.other.infra.database.rds.service.props.impl;

import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.props.RoomThemeUserBackpackDAO;
import com.red.circle.other.infra.database.rds.entity.props.RoomThemeUserBackpack;
import com.red.circle.other.infra.database.rds.service.props.RoomThemeUserBackpackService;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户房间主题背包 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2021-01-23
 */
@Service
@RequiredArgsConstructor
public class RoomThemeUserBackpackServiceImpl extends
    BaseServiceImpl<RoomThemeUserBackpackDAO, RoomThemeUserBackpack> implements
    RoomThemeUserBackpackService {


  @Override
  public List<RoomThemeUserBackpack> listByUserIdOrderByUseThemeDesc(Long userId) {
    return query()
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .gt(RoomThemeUserBackpack::getExpireTime, TimestampUtils.now().getTime())
        .orderByDesc(RoomThemeUserBackpack::getUseTheme)
        .list();
  }


  @Override
  public boolean switchUseTheme(Long userId, Long useThemeId, Boolean isFree) {

    RoomThemeUserBackpack userBackpack = query()
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .eq(RoomThemeUserBackpack::getThemeId, useThemeId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    cleanUseTheme(userId);

    if (Objects.nonNull(userBackpack)) {
      return update()
          .set(RoomThemeUserBackpack::getUseTheme, Boolean.TRUE)
          .eq(RoomThemeUserBackpack::getId, userBackpack.getId())
          .last(PageConstant.LIMIT_ONE)
          .execute();
    }

    if (Objects.equals(isFree, Boolean.TRUE)) {
      return save(new RoomThemeUserBackpack()
          .setUserId(userId)
          .setThemeId(useThemeId)
          .setExpireTime(TimestampUtils.nowPlusYear(10).getTime())
          .setUseTheme(Boolean.TRUE)
      );
    }

    return true;
  }

  @Override
  public boolean cleanUseTheme(Long userId) {
    return update()
        .set(RoomThemeUserBackpack::getUseTheme, Boolean.FALSE)
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .execute();
  }

  @Override
  public RoomThemeUserBackpack getNotExpireTimeByUserAndThemeId(Long userId, Long themeId) {
    if (Objects.isNull(userId) || Objects.isNull(themeId)) {
      return null;
    }
    return query()
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .eq(RoomThemeUserBackpack::getThemeId, themeId)
        .gt(RoomThemeUserBackpack::getExpireTime, TimestampUtils.now().getTime())
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public void addTheme(Long userId, Long themeId, Integer days) {
    if (Objects.isNull(userId) || Objects.isNull(themeId) || Objects.isNull(days)) {
      return;
    }

    // 卸下所有主题
    cleanUseTheme(userId);

    RoomThemeUserBackpack userBackpack = query()
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .eq(RoomThemeUserBackpack::getThemeId, themeId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    if (Objects.isNull(userBackpack)) {
      save(new RoomThemeUserBackpack()
          .setId(IdWorkerUtils.getId())
          .setUserId(userId)
          .setThemeId(themeId)
          .setThemeType(0)
          .setUseTheme(Boolean.TRUE)
          .setExpireTime(getExpireTime(days, null))
      );
      return;
    }

    long expireTime = getExpireTime(days, userBackpack.getExpireTime());
    userBackpack.setExpireTime(expireTime);
    userBackpack.setUseTheme(Boolean.TRUE);
    updateSelectiveById(userBackpack);
  }

  private Long getExpireTime(Integer days, Long historyExpireTime) {
    return Optional.ofNullable(historyExpireTime)
        .map(date -> TimestampUtils.expiredPlusDays(TimestampUtils.convert(historyExpireTime), days)
            .getTime())
        .orElse(TimestampUtils.nowPlusDays(days).getTime());
  }

  @Override
  public RoomThemeUserBackpack getByUserUseTheme(Long userId) {
    return query()
        .eq(RoomThemeUserBackpack::getUserId, userId)
        .eq(RoomThemeUserBackpack::getUseTheme, Boolean.TRUE)
        .last(PageConstant.LIMIT_ONE)
        .getOne();
  }

  @Override
  public List<RoomThemeUserBackpack> listByUserUseTheme(Collection<Long> userIds) {
    return query()
        .in(RoomThemeUserBackpack::getUserId, userIds)
        .eq(RoomThemeUserBackpack::getUseTheme, Boolean.TRUE)
        .last(PageConstant.LIMIT_ONE)
        .list();
  }

}
