package com.red.circle.other.app.command.user;

import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.GroupUnbanCmd;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent;
import com.red.circle.mq.rocket.business.producer.TaskMqMessage;
import com.red.circle.other.app.dto.cmd.user.relation.friend.FriendApplyApprovalCmd;
import com.red.circle.other.domain.gateway.user.ability.UserRelationsCalculatorGateway;
import com.red.circle.other.domain.model.user.ability.UserRelationsCalculator;
import com.red.circle.other.domain.model.user.ability.UserRelationsCalculator.CounterEnum;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.entity.user.friend.FriendApplyStatus;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.mongo.service.live.RoomUserBlacklistService;
import com.red.circle.other.infra.database.mongo.service.user.friend.FriendsApplyListService;
import com.red.circle.other.infra.database.rds.entity.user.user.RelationshipFriend;
import com.red.circle.other.infra.database.rds.service.user.user.RelationshipFriendService;
import com.red.circle.other.infra.database.rds.service.user.user.ShieldBlackService;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.other.inner.asserts.user.UserRelationErrorCode;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import com.red.circle.tool.core.parse.DataTypeUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;

/**
 * 用户处理好友申请.
 *
 * @author pengliang on 2021/5/6
 */
@Component
@RequiredArgsConstructor
public class UserHandleFriendApplyCmdExe {

  private final ImGroupClient imGroupClient;
  private final ShieldBlackService shieldBlackService;
  private final FriendsApplyListService friendsApplyListService;
  private final RoomUserBlacklistService roomUserBlacklistService;
  private final RoomProfileManagerService roomProfileManagerService;
  private final RelationshipFriendService relationshipFriendService;
  private final TaskMqMessage taskMqMessage;
  private final UserRelationsCalculatorGateway userRelationsCalculatorGateway;

  public void execute(FriendApplyApprovalCmd cmd) {

    if (isAgree(cmd.getAgree())) {
      try {
        relationshipFriendService
            .saveBatch(createRelationshipFriend(cmd.requiredReqUserId(), cmd.getApplyUserId()));
        userRelationsCalculatorGateway.process(
            new UserRelationsCalculator()
                .setUserId(cmd.requiredReqUserId())
                .setSubUserId(cmd.getApplyUserId())
                .setIncr(Boolean.TRUE)
                .setType(CounterEnum.FRIEND)
        );
      } catch (DuplicateKeyException ignore) {
        // 已经是好友
        ResponseAssert.failure(UserRelationErrorCode.ALREADY_FRIENDS);
      }
      // 将自己从对方的房间黑名单移除
      shieldBlackService.removeShieldBlackBothSides(cmd.requiredReqUserId(), cmd.getApplyUserId());

      RoomProfile roomProfile = roomProfileManagerService.getProfileByUserId(cmd.getApplyUserId());
      if (Objects.nonNull(roomProfile)) {

        Boolean status = ResponseAssert.requiredSuccess(
            imGroupClient.unBanGroupMember(new GroupUnbanCmd()
                .setGroupId(Objects.toString(roomProfile.getRoomAccount()))
                .setUserId(cmd.requiredReqUserId())
            )
        );
        if (Objects.equals(status, Boolean.TRUE)) {
          roomUserBlacklistService.removeBlack(roomProfile.getId(), cmd.requiredReqUserId());
        }
      }
    }

    friendsApplyListService.changeStatus(cmd.requiredReqUserId(), cmd.getApplyUserId(),
        getFriendApplyStatus(cmd.getAgree()));

    //添加好友
    taskMqMessage.sendTask(TaskApprovalEvent.builder()
            .taskId(6)
            .userId(cmd.getApplyUserId())
            .build());

    //sendPush(cmd);
  }

  private List<RelationshipFriend> createRelationshipFriend(Long userId, Long applyUserId) {
    return Arrays.asList(newRelationshipFriend(userId, applyUserId),
        newRelationshipFriend(applyUserId, userId));
  }

  private RelationshipFriend newRelationshipFriend(Long userId, Long applyUserId) {
    RelationshipFriend relationshipFriend = new RelationshipFriend()
        .setUserId(userId)
        .setFriendUserId(applyUserId);
    relationshipFriend.setCreateTime(TimestampUtils.now());
    relationshipFriend.setUpdateTime(TimestampUtils.now());
    return relationshipFriend;
  }

  private FriendApplyStatus getFriendApplyStatus(Boolean agree) {
    return isAgree(agree)
        ? FriendApplyStatus.AGREE_FRIEND
        : FriendApplyStatus.REJECT_FRIEND;
  }

  private boolean isAgree(Boolean agree) {
    return Objects.equals(agree, Boolean.TRUE);
  }

//  private NativeEventEnum getNativeEventEnum(Boolean agree) {
//    return isAgree(agree)
//        ? NativeEventEnum.AGREE_FRIEND
//        : NativeEventEnum.REJECT_FRIEND;
//  }

//  private void sendPush(FriendApplyApprovalCmd cmd) {
//    NativeEventEnum nativeEvent = getNativeEventEnum(cmd.getAgree());
//    nativePushManager.oneToOneUnicastAsync(OneToOnePushNativeParam.builder()
//        .acceptUserId(cmd.getApplyUserId())
//        .event(nativeEvent)
//        .pushParam(OneToOnePushNativeParam.createPushParam(cmd.getSysOrigin(),
//            nativeEvent.getI18nTitle(),
//            nativeEvent.getI18nBodyFormat(MapBuilder.builder()
//                .put("nickname",
//                    cacheUserProfileManagerService.getUserNickname(cmd.requiredReqUserId()))
//                .build())))
//        .build());
//  }

}
