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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.red.circle.common.business.enums.GenderEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
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.other.infra.database.rds.dao.sys.AdministratorDAO;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.entity.sys.Administrator;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.inner.enums.sys.appmanager.RoomRolesEnum;
import com.red.circle.other.inner.model.cmd.sys.AddSysAdministratorCmd;
import com.red.circle.other.inner.model.cmd.sys.AppUserDetailsQryCmd;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorInfoDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.other.inner.asserts.user.UserErrorCode;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * APP管理员表 服务实现类.
 * </p>
 *
 * @author pengliang
 * @since 2021-03-30
 */
@Service
public class AdministratorServiceImpl extends
    BaseServiceImpl<AdministratorDAO, Administrator> implements AdministratorService {

  @Override
  public Administrator getByUserId(Long userId) {
    return query().eq(Administrator::getUserId, userId).last(PageConstant.LIMIT_ONE).getOne();
  }

  @Override
  public boolean existsAdmin(Long userId) {
    return Optional.ofNullable(
            query().select(Administrator::getId)
                .eq(Administrator::getUserId, userId)
                .eq(Administrator::getStatus, 1)
                .last(PageConstant.LIMIT_ONE).getOne())
        .map(administrator -> Objects.nonNull(administrator.getId()))
        .orElse(Boolean.FALSE);
  }

  @Override
  public boolean existsSupperAdmin(Long userId) {
    return Optional.ofNullable(
            query().select(Administrator::getId, Administrator::getRoles)
                .eq(Administrator::getUserId, userId)
                .eq(Administrator::getStatus, 1)
                .last(PageConstant.LIMIT_ONE).getOne())
        .map(administrator -> RoomRolesEnum.SUPER_ADMIN.eq(administrator.getRoles()))
        .orElse(Boolean.FALSE);
  }

  @Override
  public boolean existsManager(Long userId) {
    return query()
        .select(Administrator::getId)
        .eq(Administrator::getUserId, userId)
        .eq(Administrator::getStatus, 1)
        .eq(Administrator::getRoles, RoomRolesEnum.MANAGER.name())
        .last(PageConstant.LIMIT_ONE).getOne() != null;
  }

  @Override
  public boolean existsAvailable(Set<Long> userIds) {
    return Optional.ofNullable(
            query().select(Administrator::getId)
                .in(Administrator::getUserId, userIds)
                .eq(Administrator::getStatus, 1)
                .last(PageConstant.LIMIT_ONE).getOne())
        .map(administrator -> Objects.nonNull(administrator.getId()))
        .orElse(Boolean.FALSE);
  }

  @Override
  public void addSysAdministrator(AddSysAdministratorCmd cmd) {
    Administrator sysAdministrator = query().eq(Administrator::getUserId, cmd.getUserId())
        .getOne();
    ResponseAssert.isNull(UserErrorCode.ACCOUNT_DOES_EXIST, sysAdministrator);

    Administrator administrator = new Administrator()
        .setUserId(cmd.getUserId())
        .setStatus(Boolean.FALSE)
        .setRoles(cmd.getRoles());
    administrator.setCreateTime(TimestampUtils.now());
    administrator.setCreateUser(cmd.getReqUserId());
    save(administrator);
  }

  @Override
  public PageResult<SysAdministratorInfoDTO> pageUserDetails(
      AppUserDetailsQryCmd appUserDetailsQuery) {
    IPage<SysAdministratorInfoDTO> appUserDetails = baseDAO.pageUserDetails(
        MybatisConvertor.toPage(appUserDetailsQuery.getPageQuery()), appUserDetailsQuery);

    if (CollectionUtils.isEmpty(appUserDetails.getRecords())) {
      return MybatisConvertor.toPageResult(appUserDetails);
    }

    PageResult<SysAdministratorInfoDTO> resultPage = MybatisConvertor.toPageResult(appUserDetails);

    resultPage.setRecords(appUserDetails.getRecords().stream().peek(appUserDetailsDTO -> {
      appUserDetailsDTO.setLevel(
          Objects.isNull(appUserDetailsDTO.getLevel()) ? 0 : appUserDetailsDTO.getLevel());
      appUserDetailsDTO.setUserSexName(
          GenderEnum.getGenderEnum(appUserDetailsDTO.getUserSex()).getName());
    }).collect(Collectors.toList()));

    return resultPage;
  }


}
