package com.yimeng.okr.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yimeng.okr.entity.SysUser;
import com.yimeng.okr.enums.UserRole;
import com.yimeng.okr.exception.BusinessException;
import com.yimeng.okr.mapper.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.security.crypto.password.PasswordEncoder;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class OrganizationServiceTest {

    @Mock SysDepartmentMapper departmentMapper;
    @Mock SysUserMapper userMapper;
    @Mock OkrObjectiveMapper objectiveMapper;
    @Mock PerformanceScoreMapper scoreMapper;
    @Mock PerformanceFeedbackMapper feedbackMapper;
    @Mock KpiConfigMapper kpiConfigMapper;
    @Mock PasswordEncoder passwordEncoder;
    @Mock AuthorizationService authorizationService;
    @InjectMocks OrganizationService organizationService;

    @Test
    void updateUserSuperiorRejectsCycle() {
        when(userMapper.selectById(1L)).thenReturn(user(1L, 2L));
        when(userMapper.selectById(3L)).thenReturn(user(3L, 4L));
        when(userMapper.selectById(4L)).thenReturn(user(4L, 1L));

        BusinessException ex = assertThrows(BusinessException.class,
                () -> organizationService.updateUserSuperior(1L, 3L));

        assertTrue(ex.getMessage().contains("循环"));
    }

    @Test
    void deleteUserRejectsUsersWithHistory() {
        when(userMapper.selectById(2L)).thenReturn(user(2L, null));
        when(userMapper.selectCount(any(LambdaQueryWrapper.class))).thenReturn(0L);
        when(objectiveMapper.selectCount(any(LambdaQueryWrapper.class))).thenReturn(1L);

        BusinessException ex = assertThrows(BusinessException.class,
                () -> organizationService.deleteUser(2L));

        assertTrue(ex.getMessage().contains("历史"));
    }

    @Test
    void getAllUsersRejectsNonHrViewer() {
        when(authorizationService.isHrOrAbove(7L)).thenReturn(false);

        BusinessException ex = assertThrows(BusinessException.class,
                () -> organizationService.getAllUsers(7L));

        assertEquals(403, ex.getCode());
    }

    private SysUser user(Long id, Long superiorId) {
        SysUser user = new SysUser();
        user.setId(id);
        user.setUsername("u" + id);
        user.setRealName("用户" + id);
        user.setRole(UserRole.EMPLOYEE);
        user.setSuperiorId(superiorId);
        return user;
    }
}
