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

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
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.team.BusinessDevelopmentTeamDAO;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentTeam;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentTeamService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 商务拓展团队表 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2022-06-07
 */
@Service
public class BusinessDevelopmentTeamServiceImpl extends
    BaseServiceImpl<BusinessDevelopmentTeamDAO, BusinessDevelopmentTeam> implements
    BusinessDevelopmentTeamService {

  @Override
  public List<BusinessDevelopmentTeam> listByUserId(Long userId, Long lastId) {
    return query()
        .eq(BusinessDevelopmentTeam::getUserId, userId)
        .lt(Objects.nonNull(lastId), BusinessDevelopmentTeam::getId, lastId)
        .orderByDesc(BusinessDevelopmentTeam::getId)
        .last(PageConstant.DEFAULT_LIMIT)
        .list();
  }

  @Override
  public boolean existTeam(Long agentUserId) {
    return Objects.nonNull(query()
        .eq(BusinessDevelopmentTeam::getAgentId, agentUserId)
        .last(PageConstant.LIMIT_ONE)
        .getOne());
  }

  @Override
  public Long getUserIdByTeamId(Long teamId) {

    if (Objects.isNull(teamId)) {
      return null;
    }

    BusinessDevelopmentTeam developmentTeam = query()
        .select(BusinessDevelopmentTeam::getUserId)
        .eq(BusinessDevelopmentTeam::getTeamId, teamId)
        .last(PageConstant.LIMIT_ONE)
        .getOne();

    if (Objects.isNull(developmentTeam)) {
      return null;
    }
    return developmentTeam.getUserId();
  }

  @Override
  public Long countTeamByBdUserId(Long bdUserId) {
    return query()
        .eq(BusinessDevelopmentTeam::getUserId, bdUserId)
        .count();
  }

  @Override
  public Set<Long> getTeamIdsByBdUserId(Long bdUserId) {

    return Optional.ofNullable(query()
            .eq(BusinessDevelopmentTeam::getUserId, bdUserId)
            .last(PageConstant.formatLimit(1000))
            .list()).map(
            v -> v.stream().map(BusinessDevelopmentTeam::getTeamId).collect(Collectors.toSet()))
        .orElse(Sets.newHashSet());
  }

  @Override
  public BigDecimal countThisMonthAgentTarget(Long bdUserId) {
    return baseDAO.countAgentTotalTarget(bdUserId,
        ZonedDateTimeAsiaRiyadhUtils.nowFirstDayOfMonthToInt());
  }

  @Override
  public Long getBdUserIdByTeamId(Long teamId) {
    return Optional.ofNullable(
        query()
            .select(BusinessDevelopmentTeam::getUserId)
            .eq(BusinessDevelopmentTeam::getTeamId, teamId)
            .last(PageConstant.LIMIT_ONE)
            .getOne()
    ).map(BusinessDevelopmentTeam::getUserId).orElse(null);
  }

  @Override
  public Map<Long, Long> mapTeamBdUserId(Set<Long> teamIds) {
    if (CollectionUtils.isEmpty(teamIds)) {
      return Maps.newHashMap();
    }
    return Optional.ofNullable(
            query().select(BusinessDevelopmentTeam::getUserId,
                    BusinessDevelopmentTeam::getTeamId)
                .in(BusinessDevelopmentTeam::getTeamId, teamIds)
                .list()
        ).map(teams -> teams.stream()
            .collect(Collectors.toMap(BusinessDevelopmentTeam::getTeamId,
                BusinessDevelopmentTeam::getUserId)))
        .orElseGet(Maps::newHashMap);
  }


  @Override
  public void removeBatchByTeamIds(List<Long> teamIds) {
    if (CollectionUtils.isEmpty(teamIds)) {
      return;
    }
    delete()
        .in(BusinessDevelopmentTeam::getTeamId, teamIds)
        .execute();
  }

  @Override
  public Set<Long> getBdUserIdsByTeamIds(Collection<Long> teamIds) {

    if (CollectionUtils.isEmpty(teamIds)) {
      return Sets.newHashSet();
    }

    List<BusinessDevelopmentTeam> list = query()
        .select(
            BusinessDevelopmentTeam::getId,
            BusinessDevelopmentTeam::getUserId,
            BusinessDevelopmentTeam::getTeamId)
        .in(BusinessDevelopmentTeam::getTeamId, teamIds)
        .last(PageConstant.formatLimit(teamIds.size()))
        .list();

    if (CollectionUtils.isEmpty(list)) {
      return Sets.newHashSet();
    }

    return list.stream().map(BusinessDevelopmentTeam::getUserId).collect(Collectors.toSet());
  }

  @Override
  public void addTeam(String sysOrigin, Long agentUserId, Long bdUserId, Long teamId,
      Long updateUserId) {

    BusinessDevelopmentTeam team = new BusinessDevelopmentTeam()
        .setSysOrigin(sysOrigin)
        .setAgentId(agentUserId)
        .setUserId(bdUserId)
        .setTeamId(teamId);
    team.setCreateUser(updateUserId);
    save(team);

  }

  @Override
  public List<BusinessDevelopmentTeam> listByUserId(Long userId) {
    return query().eq(BusinessDevelopmentTeam::getUserId, userId)
        .list();
  }

  @Override
  public BusinessDevelopmentTeam getByAgentId(Long agentId) {
    return query().eq(BusinessDevelopmentTeam::getAgentId, agentId)
        .last("LIMIT 1")
        .getOne();
  }

  @Override
  public void deleteAllByUserId(Long userId) {
    delete()
        .eq(BusinessDevelopmentTeam::getUserId, userId)
        .execute();
  }

  @Override
  public List<BusinessDevelopmentTeam> listAll() {
    return list();
  }

  @Override
  public List<BusinessDevelopmentTeam> listByBdUserId(Long bdUserId) {
    return query()
        .eq(BusinessDevelopmentTeam::getUserId, bdUserId)
        .list();
  }

}
