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


import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.infra.database.rds.dao.user.user.CpApplyDAO;
import com.red.circle.other.infra.database.rds.entity.user.user.CpApply;
import com.red.circle.other.infra.database.rds.service.user.user.CpApplyService;
import com.red.circle.other.infra.enums.user.user.CpApplyStatus;
import com.red.circle.other.inner.model.cmd.user.CpApplyQryCmd;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Service;

/**
 * <p>
 * CP申请记录 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-13
 */
@Service
public class CpApplyServiceImpl extends BaseServiceImpl<CpApplyDAO, CpApply> implements
    CpApplyService {

  @Override
  public void dismiss(Long requestUserId) {
    update()
        .set(CpApply::getStatus, CpApplyStatus.DISMISS)
        .set(CpApply::getUpdateTime, LocalDateTime.now())
        .set(CpApply::getUpdateUser, requestUserId)
        .eq(CpApply::getStatus, CpApplyStatus.AGREE)
        .and(where -> where.eq(CpApply::getSendApplyUserId, requestUserId)
            .or().eq(CpApply::getAcceptApplyUserId, requestUserId))
        .last(PageConstant.LIMIT_ONE)
        .execute();
  }

  @Override
  public Long getId(Long acceptApplyUserId, Long sendApplyUserId) {
    return Optional.ofNullable(
        query()
            .select(CpApply::getId)
            .eq(CpApply::getStatus, CpApplyStatus.WAIT)
            .eq(CpApply::getAcceptApplyUserId, acceptApplyUserId)
            .eq(CpApply::getSendApplyUserId, sendApplyUserId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(CpApply::getId).orElse(null);
  }

  @Override
  public boolean exists(Long acceptApplyUserId, Long sendApplyUserId) {
    return Optional.ofNullable(getId(acceptApplyUserId, sendApplyUserId)).isPresent();
  }

  @Override
  public boolean existsNotProcessSendApply(Long sendApplyUserId) {
    return Optional.ofNullable(query()
            .select(CpApply::getId)
            .eq(CpApply::getSendApplyUserId, sendApplyUserId)
            .eq(CpApply::getStatus, CpApplyStatus.WAIT)
            .getOne())
        .map(cpApply -> Objects.nonNull(cpApply.getId()))
        .orElse(Boolean.FALSE);
  }

  @Override
  public boolean changeStatusById(Long id, CpApplyStatus status) {
    return update()
        .set(CpApply::getStatus, status)
        .eq(CpApply::getId, id)
        .execute();
  }

  @Override
  public void refuseStatusWait(Long acceptApplyUserId) {
    update()
        .set(CpApply::getStatus, CpApplyStatus.REFUSE)
        .eq(CpApply::getStatus, CpApplyStatus.WAIT)
        .eq(CpApply::getAcceptApplyUserId, acceptApplyUserId)
        .execute();
  }

  @Override
  public List<CpApply> listRefuse(Long userId) {
    return query()
        .eq(CpApply::getStatus, CpApplyStatus.REFUSE)
        .eq(CpApply::getAcceptApplyUserId, userId)
        .last(PageConstant.MAX_LIMIT)
        .list();
  }

  @Override
  public PageResult<CpApply> pageCpApply(CpApplyQryCmd query) {
    return query()
        .eq(Objects.nonNull(query.getSendApplyUserId()), CpApply::getSendApplyUserId,
            query.getSendApplyUserId())
        .eq(Objects.nonNull(query.getAcceptApplyUserId()), CpApply::getAcceptApplyUserId,
            query.getAcceptApplyUserId())
        .eq(StringUtils.isNotBlank(query.getStatus()), CpApply::getStatus,
            query.getStatus())
        .orderByDesc(CpApply::getCreateTime)
        .page(query.getPageQuery());
  }

}
