package go.kr.project.system.auth.service.impl;

import go.kr.project.system.auth.mapper.AuthMapper;
import go.kr.project.system.auth.model.GroupRoleVO;
import go.kr.project.system.auth.model.RoleMenuVO;
import go.kr.project.system.auth.service.AuthService;
import go.kr.project.system.group.model.GroupSearchVO;
import go.kr.project.system.group.model.GroupVO;
import go.kr.project.system.menu.model.MenuSearchVO;
import go.kr.project.system.menu.model.MenuVO;
import go.kr.project.system.role.model.RoleSearchVO;
import go.kr.project.system.role.model.RoleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * packageName    : go.kr.project.system.auth.service.impl
 * fileName       : AuthServiceImpl
 * author         : 시스템 관리자
 * date           : 2023-06-15
 * description    : 권한 부여 관련 비즈니스 로직을 처리하는 서비스 구현체
 * ===========================================================
 * DATE              AUTHOR             NOTE
 * -----------------------------------------------------------
 * 2023-06-15        시스템 관리자       최초 생성
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthServiceImpl extends EgovAbstractServiceImpl implements AuthService {

    private final AuthMapper authMapper;

    /**
     * 역할에 할당된 메뉴 목록을 조회합니다.
     * 
     * @param roleId 역할 ID
     * @return 역할에 할당된 메뉴 목록
     */
    @Override
    public List<RoleMenuVO> selectRoleMenuList(String roleId) {
        return authMapper.selectRoleMenuList(roleId);
    }

    /**
     * 역할에 할당되지 않은 메뉴 목록을 조회합니다.
     * 
     * @param roleId 역할 ID
     * @return 역할에 할당되지 않은 메뉴 목록
     */
    @Override
    public List<MenuVO> selectUnassignedMenuList(String roleId) {
        return authMapper.selectUnassignedMenuList(roleId);
    }

    /**
     * 역할에 메뉴를 할당합니다.
     * 
     * @param roleMenuVO 역할-메뉴 매핑 정보
     * @return 할당된 행의 수
     */
    @Override
    public int insertRoleMenu(RoleMenuVO roleMenuVO) {
        return authMapper.insertRoleMenu(roleMenuVO);
    }

    /**
     * 역할에서 메뉴를 제거합니다.
     * 
     * @param roleId 역할 ID
     * @param menuId 메뉴 ID
     * @return 제거된 행의 수
     */
    @Override
    public int deleteRoleMenu(String roleId, String menuId) {
        return authMapper.deleteRoleMenu(roleId, menuId);
    }

    /**
     * 역할에 여러 메뉴를 할당합니다.
     * 
     * @param roleId 역할 ID
     * @param menuIds 메뉴 ID 목록
     * @param rgtr 등록자
     * @return 할당된 행의 수
     */
    @Override
    @Transactional
    public int assignMenusToRole(String roleId, List<String> menuIds, String rgtr) {
        // 기존 메뉴 할당 정보 삭제
        authMapper.deleteAllRoleMenu(roleId);

        // 새로운 메뉴 할당
        int count = 0;
        if (menuIds != null && !menuIds.isEmpty()) {
            for (String menuId : menuIds) {
                RoleMenuVO roleMenuVO = new RoleMenuVO();
                roleMenuVO.setRoleId(roleId);
                roleMenuVO.setMenuId(menuId);
                roleMenuVO.setRgtr(rgtr);
                count += authMapper.insertRoleMenu(roleMenuVO);
            }
        }

        return count;
    }

    /**
     * 그룹에 할당된 역할 목록을 조회합니다.
     * 
     * @param groupId 그룹 ID
     * @return 그룹에 할당된 역할 목록
     */
    @Override
    public List<GroupRoleVO> selectGroupRoleList(String groupId) {
        return authMapper.selectGroupRoleList(groupId);
    }

    /**
     * 그룹에 할당되지 않은 역할 목록을 조회합니다.
     * 
     * @param groupId 그룹 ID
     * @return 그룹에 할당되지 않은 역할 목록
     */
    @Override
    public List<RoleVO> selectUnassignedRoleList(String groupId) {
        return authMapper.selectUnassignedRoleList(groupId);
    }

    /**
     * 그룹에 역할을 할당합니다.
     * 
     * @param groupRoleVO 그룹-역할 매핑 정보
     * @return 할당된 행의 수
     */
    @Override
    public int insertGroupRole(GroupRoleVO groupRoleVO) {
        return authMapper.insertGroupRole(groupRoleVO);
    }

    /**
     * 그룹에서 역할을 제거합니다.
     * 
     * @param groupId 그룹 ID
     * @param roleId 역할 ID
     * @return 제거된 행의 수
     */
    @Override
    public int deleteGroupRole(String groupId, String roleId) {
        return authMapper.deleteGroupRole(groupId, roleId);
    }

    /**
     * 그룹에 여러 역할을 할당합니다.
     * 
     * @param groupId 그룹 ID
     * @param roleIds 역할 ID 목록
     * @param rgtr 등록자
     * @return 할당된 행의 수
     */
    @Override
    @Transactional
    public int assignRolesToGroup(String groupId, List<String> roleIds, String rgtr) {
        // 기존 역할 할당 정보 삭제
        authMapper.deleteAllGroupRole(groupId);

        // 새로운 역할 할당
        int count = 0;
        if (roleIds != null && !roleIds.isEmpty()) {
            for (String roleId : roleIds) {
                GroupRoleVO groupRoleVO = new GroupRoleVO();
                groupRoleVO.setGroupId(groupId);
                groupRoleVO.setRoleId(roleId);
                groupRoleVO.setRgtr(rgtr);
                count += authMapper.insertGroupRole(groupRoleVO);
            }
        }

        return count;
    }

    /**
     * 그룹 목록을 조회합니다.
     * 
     * @param paramVO 검색 조건을 담은 VO 객체
     * @return 그룹 목록
     */
    @Override
    public List<GroupVO> selectGroupList(GroupSearchVO paramVO) {
        return authMapper.selectGroupList(paramVO);
    }

    /**
     * 역할 목록을 조회합니다.
     * 
     * @param paramVO 검색 조건을 담은 VO 객체
     * @return 역할 목록
     */
    @Override
    public List<RoleVO> selectRoleList(RoleSearchVO paramVO) {
        return authMapper.selectRoleList(paramVO);
    }

    /**
     * 메뉴 목록을 조회합니다.
     * 
     * @param paramVO 검색 조건을 담은 VO 객체
     * @return 메뉴 목록
     */
    @Override
    public List<MenuVO> selectMenuList(MenuSearchVO paramVO) {
        return authMapper.selectMenuList(paramVO);
    }
}
