package com.red.circle.other.app.service.family;

import com.red.circle.common.business.dto.cmd.AppExtCommand;
import com.red.circle.common.business.dto.cmd.UserIdCmd;
import com.red.circle.common.business.dto.cmd.app.AppUserIdCmd;
import com.red.circle.other.app.command.family.ApplyJoinFamilyExe;
import com.red.circle.other.app.command.family.FamilyAdminExe;
import com.red.circle.other.app.command.family.FamilyBaseInfoExe;
import com.red.circle.other.app.command.family.FamilyCreateExe;
import com.red.circle.other.app.command.family.FamilyCreateRuleExe;
import com.red.circle.other.app.command.family.FamilyDailyTaskExe;
import com.red.circle.other.app.command.family.FamilyDismissGroupChatExe;
import com.red.circle.other.app.command.family.FamilyGetMembersExe;
import com.red.circle.other.app.command.family.FamilyGrantUserRoleExe;
import com.red.circle.other.app.command.family.FamilyGroupChatIsPayExe;
import com.red.circle.other.app.command.family.FamilyInfoEditExe;
import com.red.circle.other.app.command.family.FamilyLeaderboardExe;
import com.red.circle.other.app.command.family.FamilyLevelListExe;
import com.red.circle.other.app.command.family.FamilyMemberIdGetUserIdExe;
import com.red.circle.other.app.command.family.FamilyMemberListExe;
import com.red.circle.other.app.command.family.FamilyMessageHandleExe;
import com.red.circle.other.app.command.family.FamilyMessageListExe;
import com.red.circle.other.app.command.family.FamilyOnlineRoomExe;
import com.red.circle.other.app.command.family.FamilyPurchasingGroupChatExe;
import com.red.circle.other.app.command.family.FamilyRemoveUserExe;
import com.red.circle.other.app.command.family.FamilyRewardExe;
import com.red.circle.other.app.command.family.FamilyUserExitExe;
import com.red.circle.other.app.command.family.FamilyUserInfoExe;
import com.red.circle.other.app.command.family.ReceiveFamilyAwardExe;
import com.red.circle.other.app.command.family.MyFamilyApplyListExe;
import com.red.circle.other.app.command.family.CancelFamilyApplyExe;
import com.red.circle.other.app.command.family.ReapplyFamilyExe;
import com.red.circle.other.app.command.family.FamilyListExe;
import com.red.circle.other.app.command.family.FamilyBoxContributeExe;
import com.red.circle.other.app.command.family.FamilyBoxClaimExe;
import com.red.circle.other.app.command.family.FamilyHomeListExe;
import com.red.circle.other.app.command.family.FamilyMemberTop100Exe;
import com.red.circle.other.app.command.family.FamilyNewsListExe;
import com.red.circle.other.app.command.family.DisbandFamilyCmdExe;
import com.red.circle.other.app.dto.clientobject.family.*;
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
import com.red.circle.other.app.dto.cmd.family.*;
import com.red.circle.framework.dto.PageResult;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

import com.red.circle.other.app.util.DistributedLockUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * Family.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-24
 */
@Service
@RequiredArgsConstructor
public class FamilyServiceImpl implements FamilyService {

  private final FamilyAdminExe familyAdminExe;
  private final FamilyCreateExe familyCreateExe;
  private final FamilyRewardExe familyRewardExe;
  private final FamilyUserInfoExe familyUserInfoExe;
  private final FamilyBaseInfoExe familyBaseInfoExe;
  private final FamilyInfoEditExe familyInfoEditExe;
  private final FamilyUserExitExe familyUserExitExe;
  private final ApplyJoinFamilyExe applyJoinFamilyExe;
  private final FamilyDailyTaskExe familyDailyTaskExe;
  private final FamilyLevelListExe familyLevelListExe;
  private final FamilyGetMembersExe familyGetMembersExe;
  private final FamilyMemberListExe familyMemberListExe;
  private final FamilyRemoveUserExe familyRemoveUserExe;
  private final FamilyOnlineRoomExe familyOnlineRoomExe;
  private final FamilyCreateRuleExe familyCreateRuleExe;
  private final FamilyMessageListExe familyMessageListExe;
  private final FamilyLeaderboardExe familyLeaderboardExe;
  private final ReceiveFamilyAwardExe receiveFamilyAwardExe;
  private final FamilyGrantUserRoleExe familyGrantUserRoleExe;
  private final FamilyMessageHandleExe familyMessageHandleExe;
  private final FamilyGroupChatIsPayExe familyGroupChatIsPayExe;
  private final FamilyDismissGroupChatExe familyDismissGroupChatExe;
  private final FamilyMemberIdGetUserIdExe familyMemberIdGetUserIdExe;
  private final FamilyPurchasingGroupChatExe familyPurchasingGroupChatExe;
  private final MyFamilyApplyListExe myFamilyApplyListExe;
  private final CancelFamilyApplyExe cancelFamilyApplyExe;
  private final ReapplyFamilyExe reapplyFamilyExe;
  private final FamilyListExe familyListExe;
  private final FamilyBoxContributeExe familyBoxContributeExe;
  private final FamilyBoxClaimExe familyBoxClaimExe;
  private final FamilyHomeListExe familyHomeListExe;
  private final FamilyMemberTop100Exe familyMemberTop100Exe;
  private final FamilyNewsListExe familyNewsListExe;
  private final DisbandFamilyCmdExe disbandFamilyCmdExe;
  private final DistributedLockUtil distributedLockUtil;

  @Override
  public Long create(FamilyCreateCmd cmd) {
    String key = "FAMILY_CREATE_KEY" + ":" + cmd.getReqUserId();
    return distributedLockUtil.executeWithLock(key, () -> familyCreateExe.execute(cmd));
  }

  @Override
  public void edit(FamilyInfoEditCmd cmd) {
    familyInfoEditExe.execute(cmd);
  }

  @Override
  public FamilyMemberCO getAdmin(FamilyAdminQueryCmd cmd) {
    return familyAdminExe.execute(cmd);
  }

  @Override
  public FamilyMemberListCO listMember(FamilyMemberListQueryCmd cmd) {
    return familyMemberListExe.execute(cmd);
  }

  @Override
  public FamilyBaseInfoCO getBaseInfo(FamilyBaseInfoQueryCmd cmd) {
    return familyBaseInfoExe.execute(cmd);
  }

  @Override
  public FamilyBaseInfoCO getUserBaseInfo(AppUserIdCmd cmd) {
    return familyBaseInfoExe.execute2(cmd);
  }

  @Override
  public void grantUserRole(FamilyGrantUserRoleCmd cmd) {
    if (Objects.equals(cmd.getRoleKey(), "REMOVE")) {
      FamilyRemoveUserCmd removeUserCmd = new FamilyRemoveUserCmd();
      removeUserCmd.setRemoveMemberId(cmd.getAuthorizedMemberId());
      removeUserCmd.setReqUserId(cmd.getReqUserId());
      familyRemoveUserExe.execute(removeUserCmd);
      return;
    }
    familyGrantUserRoleExe.execute(cmd);
  }

  @Override
  public FamilyLeaderboardCO getLeaderboard(FamilyBaseInfoQueryCmd cmd) {
    return familyLeaderboardExe.execute(cmd);
  }

  @Override
  public FamilyLeaderboardCO getMemberTop100(FamilyBaseInfoQueryCmd cmd) {
    return familyMemberTop100Exe.execute(cmd);
  }

  @Override
  public List<FamilyLevelCO> listLevelConfig(AppExtCommand cmd) {
    return familyLevelListExe.execute(cmd);
  }

  @Override
  public void messageHandle(FamilyMessageHandleCmd cmd) {
    familyMessageHandleExe.execute(cmd);
  }

  @Override
  public List<FamilyMsgListCO> listMessage(FamilyMessageListCmd cmd) {
    return familyMessageListExe.execute(cmd);
  }

  @Override
  public List<RoomVoiceProfileCO> listOnlineRoom(FamilyOnlineRoomQueryCmd cmd) {
    return familyOnlineRoomExe.execute(cmd);
  }

  @Override
  public void removeUser(FamilyRemoveUserCmd cmd) {
    familyRemoveUserExe.execute(cmd);
  }

  @Override
  public void userExit(AppExtCommand cmd) {
    familyUserExitExe.execute(cmd);
  }

  @Override
  public FamilyUserInfoCO memberUserInfo(FamilyUserInfoQueryCmd cmd) {
    return familyUserInfoExe.execute(cmd);
  }

  @Override
  public void applyJoin(ApplyJoinFamilyCmd cmd) {
    String key = "FAMILY_APPLY_JOIN" + ":" + cmd.getFamilyId() + "_" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      applyJoinFamilyExe.execute(cmd);
    });
  }

  @Override
  public void triggerDailyTask(FamilyDailyTaskCmd cmd) {
    familyDailyTaskExe.execute(cmd);
  }

  @Override
  public FamilyCreateRulesCO familyCreateRule(AppExtCommand cmd) {
    return familyCreateRuleExe.execute(cmd);
  }

  @Override
  public FamilyRewardCO myFamilyReward(AppExtCommand cmd) {
    return familyRewardExe.execute(cmd);
  }

  @Override
  public void receiveFamilyAward(ReceiveFamilyAwardCmd cmd) {
    receiveFamilyAwardExe.execute(cmd);
  }

  @Override
  public BigDecimal purchasingFamilyGroupChat(FamilyGroupChatQueryCmd cmd) {
    return familyPurchasingGroupChatExe.execute(cmd);
  }

  @Override
  public void dismissFamilyGroupChat(FamilyGroupChatQueryCmd cmd) {

    familyDismissGroupChatExe.execute(cmd);
  }

  @Override
  public Boolean getFamilyGroupChatIsPay(FamilyGroupChatPayCheckCmd cmd) {
    return familyGroupChatIsPayExe.execute(cmd);
  }

  @Override
  public List<FamilyMemberCO> getMembers(FamilyMemberListCmd cmd) {
    return familyGetMembersExe.execute(cmd);
  }

  @Override
  public List<MyFamilyApplyCO> myApplyList(MyFamilyApplyListCmd cmd) {
    return myFamilyApplyListExe.execute(cmd);
  }

  @Override
  public void cancelFamilyApply(CancelFamilyApplyCmd cmd) {
    String key = "FAMILY_APPLY_CANCEL" + ":" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      cancelFamilyApplyExe.execute(cmd);
    });
  }

  @Override
  public void reapplyFamily(ReapplyFamilyCmd cmd) {
    String key = "FAMILY_APPLY_REAPPLY" + ":" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      reapplyFamilyExe.execute(cmd);
    });
  }

  @Override
  public PageResult<FamilyListCO> familyList(FamilyListCmd cmd) {
    return familyListExe.execute(cmd);
  }

  @Override
  public void boxContribute(FamilyBaseInfoQueryCmd cmd) {
    String key = "FAMILY_BOX_CONTRIBUTE" + ":" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      familyBoxContributeExe.execute(cmd);
    });
  }

  @Override
  public void boxClaim(FamilyBoxClaimCmd cmd) {
    String key = "FAMILY_BOX_CLAIM" + ":" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      familyBoxClaimExe.execute(cmd);
    });
  }

  @Override
  public PageResult<FamilyHomeListCO> familyHomeList(FamilyHomeListCmd cmd) {
    return familyHomeListExe.execute(cmd);
  }

  @Override
  public PageResult<FamilyNewsCO> familyNewsList(FamilyNewsListCmd cmd) {
    return familyNewsListExe.execute(cmd);
  }

  @Override
  public void disbandFamily(DisbandFamilyCmd cmd) {
    String key = "FAMILY_DISBAND" + ":" + cmd.getReqUserId();
    distributedLockUtil.executeWithLock(key, () -> {
      disbandFamilyCmdExe.execute(cmd);
    });
  }
}
