package com.red.circle.other.app.inner.service.team.impl;

import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.database.cache.service.team.BdTeamCacheService;
import com.red.circle.other.infra.database.rds.entity.team.BusinessDevelopmentBaseInfo;
import com.red.circle.other.infra.database.rds.service.team.BusinessDevelopmentBaseInfoService;
import com.red.circle.other.app.inner.convertor.team.BdInnerConvertor;
import com.red.circle.other.app.inner.service.team.BdTeamInfoClientService;
import com.red.circle.other.inner.model.cmd.team.BdTeamInfoCmd;
import com.red.circle.other.inner.model.cmd.team.bd.BdTeamPageQryCmd;
import com.red.circle.other.inner.model.cmd.team.bd.BdTeamUpdateOpsCmd;
import com.red.circle.other.inner.model.cmd.team.bd.BdTeamWorkStatisticsQryCmd;
import com.red.circle.other.inner.model.cmd.team.bd.ChangeBdLeaderCmd;
import com.red.circle.other.inner.model.dto.agency.bd.BdTeamInfoDTO;
import com.red.circle.tool.core.text.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * bd 服务实现.
 *
 * @author pengliang on 2023/6/1
 */
@Service
@RequiredArgsConstructor
public class BdTeamInfoClientServiceImpl implements BdTeamInfoClientService {

  private final BdInnerConvertor bdAppConvertor;
  private final BusinessDevelopmentBaseInfoService businessDevelopmentBaseInfoService;
  private final UserProfileGateway userProfileGateway;
  private final BdTeamCacheService bdTeamCacheService;

  @Override
  public Boolean check(Long userId) {
    return businessDevelopmentBaseInfoService.checkBD(userId);
  }

  @Override
  public BdTeamInfoDTO getByUserId(Long userId) {
    return bdAppConvertor.toBdTeamInfoDTO(businessDevelopmentBaseInfoService.getByUserId(userId));
  }

  @Override
  public BdTeamInfoDTO getById(Long id) {
    return bdAppConvertor.toBdTeamInfoDTO(businessDevelopmentBaseInfoService.getById(id));
  }

  @Override
  public void addBdInfo(BdTeamInfoCmd cmd) {
    BusinessDevelopmentBaseInfo bdInfo = bdAppConvertor.toRoomBusinessDevelopmentBaseInfo(cmd);
    businessDevelopmentBaseInfoService.save(bdInfo);
    bdTeamCacheService.clearRelationChangeCaches(
        bdInfo.getBdLeadUserId(),
        bdInfo.getBdLeadUserId(),
        bdInfo.getUserId());
  }

  @Override
  public void incrMemberCount(Set<Long> userIds) {
    businessDevelopmentBaseInfoService.incrMemberCount(userIds);
  }

  @Override
  public Map<Long, Boolean> mapCheckBd(Set<Long> userIds) {
    return businessDevelopmentBaseInfoService.mapCheckBd(userIds);
  }

  @Override
  public void updateSelectiveById(BdTeamInfoDTO dto) {
    BusinessDevelopmentBaseInfo oldBdInfo = businessDevelopmentBaseInfoService.getById(dto.getId());
    businessDevelopmentBaseInfoService.updateSelectiveById(
        bdAppConvertor.toBusinessDevelopmentBaseInfo(dto)
    );
    if (Objects.nonNull(oldBdInfo)) {
      Long newLeaderUserId = Objects.nonNull(dto.getBdLeadUserId())
          ? dto.getBdLeadUserId()
          : oldBdInfo.getBdLeadUserId();
      bdTeamCacheService.clearRelationChangeCaches(
          oldBdInfo.getBdLeadUserId(),
          newLeaderUserId,
          oldBdInfo.getUserId());
    }
  }

  @Override
  public void updateOpsById(BdTeamUpdateOpsCmd cmd) {
    businessDevelopmentBaseInfoService.update()
        .set(BusinessDevelopmentBaseInfo::getUpdateUser, cmd.getUpdateUser())
        .set(BusinessDevelopmentBaseInfo::getContact, cmd.getContact())
        .set(BusinessDevelopmentBaseInfo::getRegion, cmd.getRegion())
        .eq(BusinessDevelopmentBaseInfo::getId, cmd.getId())
        .execute();
  }

  @Override
  public void decrMemberCount(Set<Long> userIds) {
    businessDevelopmentBaseInfoService.decrMemberCount(userIds);
  }

  @Override
  public PageResult<BdTeamInfoDTO> pageOps(BdTeamPageQryCmd qryCmd) {
    Long startMemberQuantity = null;
    Long endMemberQuantity = null;
    if (StringUtils.isNotBlank(qryCmd.getMemberQuantityRange())) {
      String[] ranges = StringUtils.split(qryCmd.getMemberQuantityRange(), "~");
      if (ranges.length == 2) {
        startMemberQuantity = Long.parseLong(ranges[0]);
        endMemberQuantity = Long.parseLong(ranges[1]);
      }
    }

    return bdAppConvertor.toPageBdTeamInfoDTO(
        businessDevelopmentBaseInfoService.query()
            .eq(Objects.nonNull(qryCmd.getUserId()), BusinessDevelopmentBaseInfo::getUserId,
                qryCmd.getUserId())
            .eq(StringUtils.isNotBlank(qryCmd.getRegion()), BusinessDevelopmentBaseInfo::getRegion,
                qryCmd.getRegion())
            .eq(StringUtils.isNotBlank(qryCmd.getSysOrigin()),
                BusinessDevelopmentBaseInfo::getSysOrigin,
                qryCmd.getSysOrigin())
            .eq(Objects.nonNull(qryCmd.getCreateUser()), BusinessDevelopmentBaseInfo::getCreateUser,
                qryCmd.getCreateUser())
            .eq(Objects.nonNull(qryCmd.getBdLeadUserId()),
                BusinessDevelopmentBaseInfo::getBdLeadUserId, qryCmd.getBdLeadUserId())
            .ge(Objects.nonNull(startMemberQuantity),
                BusinessDevelopmentBaseInfo::getMemberQuantity, startMemberQuantity)
            .le(Objects.nonNull(endMemberQuantity),
                BusinessDevelopmentBaseInfo::getMemberQuantity, endMemberQuantity)
            .orderByDesc(BusinessDevelopmentBaseInfo::getCreateTime)
            .page(qryCmd.getPageQuery())
    );
  }

  @Override
  public List<BdTeamInfoDTO> pageWorkStatistics(BdTeamWorkStatisticsQryCmd qryCmd) {
    return bdAppConvertor.toListBdTeamInfoDTO(businessDevelopmentBaseInfoService.query()
        .eq(Objects.nonNull(qryCmd.getUserId()), BusinessDevelopmentBaseInfo::getUserId,
            qryCmd.getUserId())
        .eq(StringUtils.isNotBlank(qryCmd.getRegion()), BusinessDevelopmentBaseInfo::getRegion,
            qryCmd.getRegion())
        .eq(StringUtils.isNotBlank(qryCmd.getSysOrigin()),
            BusinessDevelopmentBaseInfo::getSysOrigin,
            qryCmd.getSysOrigin()).list());
  }

  @Override
  public void deleteById(Long id) {
    BusinessDevelopmentBaseInfo bdInfo = businessDevelopmentBaseInfoService.getById(id);
    businessDevelopmentBaseInfoService.removeById(id);
    if (Objects.nonNull(bdInfo)) {
      bdTeamCacheService.clearRelationChangeCaches(
          bdInfo.getBdLeadUserId(),
          null,
          bdInfo.getUserId());
    }
  }

  @Override
  public void changeBdLeader(ChangeBdLeaderCmd cmd) {
    // 查询BD记录
    BusinessDevelopmentBaseInfo bdInfo = businessDevelopmentBaseInfoService.getById(cmd.getBdId());
    if (Objects.isNull(bdInfo)) {
      throw new RuntimeException("BD记录不存在");
    }

    // 校验新BD Leader是否存在
    UserProfile userProfile = userProfileGateway.getByAccount(SysOriginPlatformEnum.LIKEI.name(), String.valueOf(cmd.getNewAccount()));
    if (userProfile == null) {
      throw new RuntimeException("用户不存在");
    }

    // 修改BD Leader
    businessDevelopmentBaseInfoService.update()
        .set(BusinessDevelopmentBaseInfo::getBdLeadUserId, userProfile.getId())
        .set(BusinessDevelopmentBaseInfo::getUpdateUser, cmd.getUpdateUser())
        .eq(BusinessDevelopmentBaseInfo::getId, cmd.getBdId())
        .execute();

    bdTeamCacheService.clearRelationChangeCaches(
        bdInfo.getBdLeadUserId(),
        userProfile.getId(),
        bdInfo.getUserId());
  }


}
