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

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.red.circle.external.inner.endpoint.oss.OssServiceClient;
import com.red.circle.framework.core.dto.ReqSysOrigin;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.cmd.user.user.UserProfileModifyCmd;
import com.red.circle.other.domain.gateway.approval.ProfileApprovalGateway;
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.cp.CpRelationshipCacheService;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.sys.SysCountryCode;
import com.red.circle.other.infra.database.rds.service.sys.SysCountryCodeService;
import com.red.circle.other.infra.database.rds.service.user.user.BaseInfoService;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.component.redis.service.RedisService;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

class UpdateUserProfileCmdExeTest {

  @Test
  void execute_shouldSyncCountryToUpdateUserProfileWhenCountryChanges() {
    OssServiceClient ossServiceClient = mock(OssServiceClient.class);
    UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
    RedisService redisService = mock(RedisService.class);
    BaseInfoService baseInfoService = mock(BaseInfoService.class);
    SysCountryCodeService sysCountryCodeService = mock(SysCountryCodeService.class);
    ProfileApprovalGateway profileApprovalGateway = mock(ProfileApprovalGateway.class);
    UserProfileAppConvertor userProfileAppConvertor = mock(UserProfileAppConvertor.class);
    RoomProfileManagerService roomProfileManagerService = mock(RoomProfileManagerService.class);
    CpRelationshipCacheService cpRelationshipCacheService = mock(CpRelationshipCacheService.class);
    UpdateUserProfileCmdExe exe = new UpdateUserProfileCmdExe(
        ossServiceClient,
        userProfileGateway,
        redisService,
        baseInfoService,
        sysCountryCodeService,
        profileApprovalGateway,
        userProfileAppConvertor,
        roomProfileManagerService,
        cpRelationshipCacheService
    );

    UserProfileModifyCmd cmd = new UserProfileModifyCmd();
    cmd.setReqUserId(1L);
    cmd.setReqSysOrigin(ReqSysOrigin.of("LIKEI", "LIKEI"));
    cmd.setCountryId(2L);

    UserProfile currentUserProfile = new UserProfile();
    currentUserProfile.setId(1L);
    currentUserProfile.setCountryId(1L);
    currentUserProfile.setCountryCode("KSA");
    currentUserProfile.setCountryName("KSA");
    UserProfile updateUserProfile = new UserProfile();
    SysCountryCode newCountry = new SysCountryCode()
        .setId(2L)
        .setAlphaTwo("JP")
        .setCountryName("Japan");

    when(userProfileGateway.getByUserId(1L)).thenReturn(currentUserProfile);
    when(userProfileAppConvertor.toUserProfile(cmd)).thenReturn(updateUserProfile);
    when(sysCountryCodeService.getById(2L)).thenReturn(newCountry);
    when(userProfileAppConvertor.toUserProfileDTO(currentUserProfile)).thenReturn(new UserProfileDTO());

    exe.execute(cmd);

    ArgumentCaptor<UserProfile> updateCaptor = ArgumentCaptor.forClass(UserProfile.class);
    verify(userProfileGateway).updateSelectiveById(updateCaptor.capture());
    UserProfile persistedUpdate = updateCaptor.getValue();
    assertEquals(2L, persistedUpdate.getCountryId());
    assertEquals("JP", persistedUpdate.getCountryCode());
    assertEquals("Japan", persistedUpdate.getCountryName());
    verify(roomProfileManagerService).updateUserCountry(1L, "JP", "Japan");
  }
}
