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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.convertor.MybatisConvertor;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.InviteUserRegisterDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.InviteUserRegister;
import com.red.circle.other.infra.database.rds.query.user.InviteUserQry;
import com.red.circle.other.infra.database.rds.service.user.user.InviteUserRegisterService;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户邀请用户注册信息表 服务实现类
 * </p>
 *
 * @author pengliang
 * @since 2020-02-12
 */
@Service
@AllArgsConstructor
public class InviteUserRegisterServiceImpl extends
    BaseServiceImpl<InviteUserRegisterDAO, InviteUserRegister> implements
    InviteUserRegisterService {

  private final InviteUserRegisterDAO inviteUserRegisterDAO;

  @Override
  public boolean existsByInviteUserId(Long inviteUserId) {
    return Optional.ofNullable(
        query()
            .select(InviteUserRegister::getId)
            .eq(InviteUserRegister::getInviteUserId, inviteUserId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(inviteUserRegister -> Objects.nonNull(inviteUserRegister.getId())).orElse(Boolean.FALSE);
  }

  @Override
  public boolean existsByDeviceId(String deviceId) {
    return Optional.ofNullable(
        query()
            .select(InviteUserRegister::getId)
            .eq(InviteUserRegister::getDeviceId, deviceId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(inviteUserRegister -> Objects.nonNull(inviteUserRegister.getId())).orElse(Boolean.FALSE);
  }

  @Override
  public Long getUserIdByInviteUserId(Long inviteUserId) {
    return Optional.ofNullable(
        query()
            .select(InviteUserRegister::getUserId)
            .eq(InviteUserRegister::getInviteUserId, inviteUserId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(InviteUserRegister::getUserId).orElse(null);
  }

  @Override
  public InviteUserRegister getByInviteUserId(Long inviteUserId) {
    return Optional.ofNullable(
        query()
            .eq(InviteUserRegister::getInviteUserId, inviteUserId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).orElse(null);
  }

  @Override
  public List<Long> listInviteRecord(SysOriginPlatformEnum sysOrigin, Long userId,
      Long lastId) {
    return Optional.ofNullable(query()
            .select(InviteUserRegister::getInviteUserId)
            .eq(InviteUserRegister::getSysOrigin, sysOrigin)
            .eq(InviteUserRegister::getUserId, userId)
            .lt(Objects.nonNull(lastId), InviteUserRegister::getId, lastId)
            .orderByDesc(InviteUserRegister::getId)
            .last(PageConstant.DEFAULT_LIMIT)
            .list())
        .map(inviteUserRegisters -> inviteUserRegisters.stream()
            .map(InviteUserRegister::getInviteUserId).collect(
                Collectors.toList()))
        .orElse(CollectionUtils.newArrayList());
  }

  @Override
  public List<InviteUserRegister> pageByCommissionDesc(Integer pageNumber, Long userId) {

    if (Objects.isNull(pageNumber) || pageNumber < 1) {
      pageNumber = 1;
    }

    return query()
        .eq(InviteUserRegister::getUserId, userId)
        .orderByDesc(InviteUserRegister::getCommission)
        .last(getPageSql(pageNumber))
        .list();
  }

  private String getPageSql(Integer pageNumber) {
    return String.format("LIMIT %s, %s", (pageNumber - 1) * PageConstant.DEFAULT_LIMIT_SIZE,
        PageConstant.DEFAULT_LIMIT_SIZE);
  }

  @Override
  public void incrCommission(Long inviteUserId, BigDecimal commission) {

    update().set(InviteUserRegister::getUpdateTime, TimestampUtils.now())
        .setSql("commission=commission+" + commission)
        .eq(InviteUserRegister::getInviteUserId, inviteUserId)
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public PageResult<InviteUserRegister> pageQuery(
      IPage<InviteUserRegister> page, InviteUserQry query) {

    return MybatisConvertor.toPageResult(inviteUserRegisterDAO.pageQuery(page, query));

  }
}
