package com.njcn.rdms.module.system.api.permission;

import com.njcn.rdms.framework.common.pojo.CommonResult;
import com.njcn.rdms.framework.test.core.ut.BaseMockitoUnitTest;
import com.njcn.rdms.module.system.api.permission.dto.UserVisibilityConfigRespDTO;
import com.njcn.rdms.module.system.dal.dataobject.permission.UserVisibilityConfigDO;
import com.njcn.rdms.module.system.service.dept.DeptService;
import com.njcn.rdms.module.system.service.permission.UserVisibilityConfigService;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;

import java.util.List;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

class UserVisibilityConfigApiImplTest extends BaseMockitoUnitTest {

    @Mock
    private UserVisibilityConfigService userVisibilityConfigService;

    @Mock
    private DeptService deptService;

    @InjectMocks
    private UserVisibilityConfigApiImpl userVisibilityConfigApi;

    /** 用户无配置时返回 null data，不抛异常 */
    @Test
    void getConfig_returnsNull_whenNoConfig() {
        when(userVisibilityConfigService.getByUserId(1L)).thenReturn(null);

        CommonResult<UserVisibilityConfigRespDTO> result = userVisibilityConfigApi.getConfig(1L);

        assertNull(result.getCheckedData());
    }

    /** type=all 时，directionCodes / projectIds 均不填充 */
    @Test
    void getConfig_returnsAllType_withoutDirectionsOrProjects() {
        UserVisibilityConfigDO cfg = buildDO(1L, "all", null, null);
        when(userVisibilityConfigService.getByUserId(1L)).thenReturn(cfg);

        CommonResult<UserVisibilityConfigRespDTO> result = userVisibilityConfigApi.getConfig(1L);

        UserVisibilityConfigRespDTO dto = result.getCheckedData();
        assertEquals("all", dto.getType());
        assertNull(dto.getDirectionCodes());
        assertNull(dto.getProjectIds());
    }

    /** type=directions 时，directionIds 经 deptService.listCodesByIds 转换为 code 集合 */
    @Test
    void getConfig_returnsDirectionsTypeWithCodes() {
        List<Long> directionIds = List.of(101L, 102L);
        UserVisibilityConfigDO cfg = buildDO(2L, "directions", directionIds, null);
        when(userVisibilityConfigService.getByUserId(2L)).thenReturn(cfg);
        when(deptService.listCodesByIds(directionIds)).thenReturn(Set.of("dir_code_A", "dir_code_B"));

        CommonResult<UserVisibilityConfigRespDTO> result = userVisibilityConfigApi.getConfig(2L);

        UserVisibilityConfigRespDTO dto = result.getCheckedData();
        assertEquals("directions", dto.getType());
        assertEquals(Set.of("dir_code_A", "dir_code_B"), dto.getDirectionCodes());
        assertNull(dto.getProjectIds());
    }

    /** type=projects 时，projectIds 直接透传到 DTO，不调用 deptService */
    @Test
    void getConfig_returnsProjectsType() {
        List<Long> projectIds = List.of(201L, 202L);
        UserVisibilityConfigDO cfg = buildDO(3L, "projects", null, projectIds);
        when(userVisibilityConfigService.getByUserId(3L)).thenReturn(cfg);

        CommonResult<UserVisibilityConfigRespDTO> result = userVisibilityConfigApi.getConfig(3L);

        UserVisibilityConfigRespDTO dto = result.getCheckedData();
        assertEquals("projects", dto.getType());
        assertNull(dto.getDirectionCodes());
        assertTrue(dto.getProjectIds().containsAll(Set.of(201L, 202L)));
        assertEquals(2, dto.getProjectIds().size());
    }

    // ===== 辅助方法 =====

    private static UserVisibilityConfigDO buildDO(Long userId, String type,
                                                   List<Long> directionIds,
                                                   List<Long> projectIds) {
        UserVisibilityConfigDO do_ = new UserVisibilityConfigDO();
        do_.setUserId(userId);
        do_.setVisibilityType(type);
        do_.setVisibleDirectionIds(directionIds);
        do_.setVisibleProjectIds(projectIds);
        return do_;
    }

}
