package com.red.circle.console.app.service.app.room;

import com.red.circle.console.app.dto.clienobject.room.RoomMemberCO;
import com.red.circle.console.app.dto.cmd.app.room.ChangeRoomMemberRoleCmd;
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.live.RoomManagerClient;
import com.red.circle.other.inner.endpoint.live.RoomMemberClient;
import com.red.circle.other.inner.enums.live.RoomUserRolesEnum;
import com.red.circle.other.inner.model.cmd.room.RoomMemberOpsPageQryCmd;
import com.red.circle.other.inner.model.dto.live.RoomMemberDTO;
import com.red.circle.other.inner.model.dto.live.RoomProfileDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 成员列表 服务类 实现.
 *
 * @author pengliang on 2023/11/22
 */
@Service
@RequiredArgsConstructor
public class RoomMemberServiceImpl implements RoomMemberService {

  private final RoomMemberClient roomMemberClient;
  private final RoomManagerClient roomManagerClient;
  private final UserProfileClient userProfileClient;

  @Override
  public PageResult<RoomMemberCO> pageOps(RoomMemberOpsPageQryCmd qryCmd) {

    PageResult<RoomMemberDTO> pageResult = roomMemberClient.pageOps(qryCmd).getBody();

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

    Map<Long, UserProfileDTO> userProfileDTOMap = userProfileClient
        .mapByUserIds(pageResult.getRecords().stream()
            .map(RoomMemberDTO::getUserId).collect(Collectors.toSet())
        ).getBody();

    return pageResult.convert(roomMember -> new RoomMemberCO()
        .setId(roomMember.getId())
        .setUserProfile(userProfileDTOMap.get(roomMember.getUserId()))
        .setRoomRole(roomMember.getRoles())
        .setCreateTime(roomMember.getCreateTime())
    );
  }

  @Override
  public void changeRole(ChangeRoomMemberRoleCmd cmd) {

    RoomUserRolesEnum rolesEnum = RoomUserRolesEnum.valueOf(cmd.getRoles());

    RoomProfileDTO roomProfile = Optional.ofNullable(
            userProfileClient.getByAccount(cmd.getSysOrigin(), cmd.getRoomAccount()).getBody()
        )
        .map(userProfile ->
            roomManagerClient.getProfileByUserId(userProfile.getId()).getBody())
        .orElse(null);

    ResponseAssert.notNull(ConsoleErrorCode.NOT_FOUND_ROOM, roomProfile);

    UserProfileDTO userProfile = userProfileClient.getByAccount(roomProfile.getSysOrigin(),
        cmd.getUserAccount()).getBody();
    ResponseAssert.notNull(ConsoleErrorCode.USER_NOT_FOUND, userProfile);

    ResponseAssert.isTrue(ConsoleErrorCode.INCONSISTENT_ATTRIBUTION_SYSTEM,
        Objects.equals(userProfile.getOriginSys(), cmd.getSysOrigin()));

    RoomMemberDTO roomMember = roomMemberClient.getMember(roomProfile.getId(), userProfile.getId())
        .getBody();
    ResponseAssert.isFalse(ConsoleErrorCode.NOT_ROLE_CHANGE_HOMEOWNER,
        Objects.nonNull(roomMember) && Objects
            .equals(roomMember.getRoles(), RoomUserRolesEnum.HOMEOWNER.name()));

    if (checkNotChangeRoles(cmd, roomMember)) {
      return;
    }

    //清除房间用户缓存
    roomManagerClient.removeCacheUserRole(userProfile.getId(), roomProfile.getId());

    // 入参角色为游客处理
    if (cmd.checkRoleTourist()) {
      handlerChangeTourist(roomMember);
      return;
    }

    // 入参角色为成员 || 管理员
    if (cmd.checkRoleMember() || cmd.checkRoleAdmin()) {
      handlerChangeMemberOrAdmin(cmd, roomProfile, userProfile, roomMember);
      return;
    }

    // 其余角色无权限操作
    ResponseAssert.failure(CommonErrorCode.OPERATING_FAILURE);
  }

  private void handlerChangeMemberOrAdmin(ChangeRoomMemberRoleCmd cmd,
      RoomProfileDTO roomProfile,
      UserProfileDTO userProfile,
      RoomMemberDTO roomMember) {

    if (Objects.isNull(roomMember)) {

      // 添加成员，并且成员数 +1
      addRoomMember(cmd, roomProfile, userProfile);
      // roomProfileManagerService.incrCounterAdmin();
      incrCounter(roomProfile.getId(), RoomUserRolesEnum.valueOf(cmd.getRoles()));
      return;
    }

    // 修改角色，原角色数量 -1
    roomMemberClient.updateRole(roomMember.getId(), cmd.getRoles(), cmd.getUpdateUser());
    decrCounter(roomProfile.getId(), RoomUserRolesEnum.valueOf(roomMember.getRoles()));

    // 新角色 +1
    incrCounter(roomProfile.getId(), RoomUserRolesEnum.valueOf(cmd.getRoles()));
  }

  private void incrCounter(Long roomId, RoomUserRolesEnum roomUserRoles) {
    if (Objects.equals(RoomUserRolesEnum.ADMIN, roomUserRoles)) {
      roomManagerClient.incrCounterAdmin(roomId);
      return;
    }
    roomManagerClient.incrCounterMember(roomId);
  }

  private void decrCounter(Long roomId, RoomUserRolesEnum roomUserRoles) {
    if (Objects.equals(RoomUserRolesEnum.ADMIN, roomUserRoles)) {
      roomManagerClient.decrCounterAdmin(roomId);
      return;
    }
    roomManagerClient.decrCounterMember(roomId);
  }

  private void addRoomMember(ChangeRoomMemberRoleCmd cmd, RoomProfileDTO roomProfile,
      UserProfileDTO userProfile) {
    RoomMemberDTO saveRoomMember = new RoomMemberDTO();
    saveRoomMember.setSysOrigin(userProfile.getOriginSys());
    saveRoomMember.setRoles(cmd.getRoles());
    saveRoomMember.setUserId(userProfile.getId());
    saveRoomMember.setRoomId(roomProfile.getId());
    saveRoomMember.setCreateUser(cmd.getUpdateUser());
    saveRoomMember.setCreateTime(cmd.getUpdateTime());
    saveRoomMember.setUpdateUser(cmd.getUpdateUser());
    ResponseAssert.requiredSuccess(roomMemberClient.add(saveRoomMember));
  }

  private boolean checkNotChangeRoles(ChangeRoomMemberRoleCmd cmd, RoomMemberDTO roomMember) {
    return Objects.nonNull(roomMember) && Objects.equals(roomMember.getRoles(),
        cmd.getRoles());
  }

  private void handlerChangeTourist(RoomMemberDTO roomMember) {

    if (Objects.isNull(roomMember)) {
      return;
    }
    //移除房间游客
    if (!Objects.equals(roomMemberClient.deleteById(roomMember.getId()).getBody(), Boolean.TRUE)) {
      return;
    }
    //将游客数量 - 1
    decrCounter(roomMember.getRoomId(), RoomUserRolesEnum.valueOf(roomMember.getRoles()));
  }

}
