package com.red.circle.console.app.service.app.team.manager;

import com.red.circle.console.app.dto.clienobject.team.manager.TeamManagerCO;
import com.red.circle.console.app.dto.cmd.app.team.manager.TeamManagerAddCmd;
import com.red.circle.console.app.dto.cmd.app.team.manager.TeamManagerUpdateCmd;
import com.red.circle.console.infra.database.rds.entity.admin.User;
import com.red.circle.console.infra.database.rds.service.admin.UserService;
import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.endpoint.team.manager.TeamManagerClient;
import com.red.circle.other.inner.endpoint.team.target.UserHistoryIdentityClient;
import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.team.manager.TeamManagerOpsPageQryCmd;
import com.red.circle.other.inner.model.dto.agency.manager.TeamManagerDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 团队经理管理实现.
 */
@Service
@RequiredArgsConstructor
public class TeamManagerServiceImpl implements TeamManagerService {

  private final UserService userService;
  private final TeamManagerClient teamManagerClient;
  private final UserProfileClient userProfileClient;
  private final RegionConfigClient regionConfigClient;
  private final UserHistoryIdentityClient userHistoryIdentityClient;

  @Override
  public PageResult<TeamManagerCO> pageOps(TeamManagerOpsPageQryCmd qryCmd) {
    PageResult<TeamManagerDTO> pageResult = ResponseAssert.requiredSuccess(
        teamManagerClient.pageOps(qryCmd));

    if (pageResult.checkRecordsEmpty()) {
      return pageResult.emptyRecords();
    }

    Map<Long, User> sysUserMap = userService.mapBackUser(
        Stream.of(pageResult.getRecords().stream()
                    .filter(info -> Objects.nonNull(info.getCreateUser())
                        && info.getCreateUser() > 0)
                    .map(TeamManagerDTO::getCreateUser)
                    .collect(Collectors.toSet()),
                pageResult.getRecords().stream()
                    .filter(info -> Objects.nonNull(info.getUpdateUser())
                        && info.getUpdateUser() > 0)
                    .map(TeamManagerDTO::getUpdateUser)
                    .collect(Collectors.toSet()))
            .flatMap(Collection::stream)
            .collect(Collectors.toSet()));

    Map<Long, UserProfileDTO> userProfileMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(pageResult.getRecords().stream()
            .map(TeamManagerDTO::getUserId)
            .collect(Collectors.toSet())));

    Map<String, String> regionNameMap = ResponseAssert.requiredSuccess(
        regionConfigClient.mapRegionNameByRegionIds(
            pageResult.getRecords().stream()
                .map(TeamManagerDTO::getRegionId)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toSet())));

    return pageResult.convert(info -> new TeamManagerCO()
        .setId(info.getId())
        .setSysOrigin(info.getSysOrigin())
        .setUserProfile(userProfileMap.get(info.getUserId()))
        .setContact(info.getContact())
        .setCreateUserName(
            Optional.ofNullable(sysUserMap.get(info.getCreateUser())).map(User::getNickname)
                .orElse(""))
        .setUpdateUserName(
            Optional.ofNullable(sysUserMap.get(info.getUpdateUser())).map(User::getNickname)
                .orElse(""))
        .setRegionId(info.getRegionId())
        .setRegionName(regionNameMap.get(info.getRegionId()))
        .setCreateTime(info.getCreateTime())
        .setUpdateTime(info.getUpdateTime()));
  }

  @Override
  public void add(com.red.circle.console.app.dto.cmd.app.team.manager.TeamManagerAddCmd cmd) {
    UserProfileDTO userProfile = ResponseAssert.requiredSuccess(
        userProfileClient.getByUserId(cmd.getUserId()));
    ResponseAssert.notNull(ConsoleErrorCode.USER_INFO_NOT_FOUND, userProfile);

    ResponseAssert.isFalse(ConsoleErrorCode.USER_ALREADY_EXISTS,
        ResponseAssert.requiredSuccess(teamManagerClient.check(cmd.getUserId())));

    com.red.circle.other.inner.model.cmd.team.manager.TeamManagerAddCmd addCmd =
        new com.red.circle.other.inner.model.cmd.team.manager.TeamManagerAddCmd()
        .setId(IdWorkerUtils.getId())
        .setUserId(cmd.getUserId())
        .setSysOrigin(cmd.getSysOrigin())
        .setContact(cmd.getContact())
        .setRegionId(cmd.getRegionId())
        .setCreateUser(cmd.getCreateUser());

    ResponseAssert.requiredSuccess(teamManagerClient.add(addCmd));
    ResponseAssert.requiredSuccess(userHistoryIdentityClient.saveManager(cmd.getUserId()));
  }

  @Override
  public void update(TeamManagerUpdateCmd cmd) {
    ResponseAssert.requiredSuccess(teamManagerClient.updateSelectiveById(new TeamManagerDTO()
        .setId(cmd.getId())
        .setContact(cmd.getContact())
        .setRegionId(cmd.getRegionId())
        .setUpdateUser(cmd.getUpdateUser())));
  }

  @Override
  public void delete(Long id, Long updateUser) {
    TeamManagerDTO db = ResponseAssert.requiredSuccess(teamManagerClient.getById(id));
    ResponseAssert.notNull(CommonErrorCode.DATA_ERROR, db);
    ResponseAssert.requiredSuccess(teamManagerClient.deleteById(id));
  }

}
