package incheon.ags.ias.userRole.service.impl;

import incheon.ags.ias.myAuthrtAply.mapper.MyAuthrtAplyMapper;
import incheon.ags.ias.userRole.mapper.UserRoleMapper;
import incheon.ags.ias.userRole.service.UserRoleService;
import incheon.ags.ias.userRole.vo.UserRoleSearchVO;
import incheon.ags.ias.userRole.vo.UserRoleVO;
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;
import java.util.Map;

@Slf4j
@Service("userAuthService")
@RequiredArgsConstructor
public class UserRoleServiceImpl extends EgovAbstractServiceImpl implements UserRoleService {
    private final UserRoleMapper userRoleMapper;
    private final MyAuthrtAplyMapper myAuthrtAplyMapper;

    @Override
    public List<Map<String, Object>> selectUserRoleList(UserRoleSearchVO userRoleSearchVO) throws Exception {
        log.debug("사용자 역할 목록 조회 요청 - 검색조건: {}", userRoleSearchVO);
        List<Map<String, Object>> result = userRoleMapper.selectUserRoleList(userRoleSearchVO);
        log.debug("사용자 역할 목록 조회 완료 - 조회건수: {}", result.size());
        return result;
    }

    @Override
    public List<Map<String, Object>> selectUserRole(UserRoleVO userAuthrtVO) throws Exception{
        log.debug("사용자 역할 조회 요청 - 사용자ID: {}", userAuthrtVO.getUserId());
        return userRoleMapper.selectUserRole(userAuthrtVO);
    }

    @Override
    public List<Map<String, Object>> selectUserRoleHistory(UserRoleVO userAuthrtVO) throws Exception{
        log.debug("사용자 역할 이력 조회 요청 - 사용자ID: {}", userAuthrtVO.getUserId());
        return userRoleMapper.selectUserRoleHistory(userAuthrtVO);
    }

    @Override
    public List<Map<String, Object>> selectUserRoleHistoryForPaging(UserRoleVO userRoleVO) throws Exception {
        log.debug("사용자 역할 이력 페이징 조회 요청 - 사용자ID: {}, 페이지: {}", userRoleVO.getUserId(), userRoleVO.getPageIndex());
        return userRoleMapper.selectUserRoleHistoryForPaging(userRoleVO);
    }

    @Override
    public int selectUserRoleHistoryCnt(UserRoleVO userRoleVO) throws Exception {
        log.debug("사용자 역할 이력 총 개수 조회 요청 - 사용자ID: {}", userRoleVO.getUserId());
        return userRoleMapper.selectUserRoleHistoryCnt(userRoleVO);
    }

    @Override
    public UserRoleVO selectUserRoleDetail(UserRoleVO userRoleVO) throws Exception {
        log.debug("사용자 역할 상세 조회 요청 - 사용자ID: {}, 역할코드: {}",
                userRoleVO.getUserId(), userRoleVO.getRoleCd());
        UserRoleVO result = userRoleMapper.selectUserRoleDetail(userRoleVO);
        if (result == null) {
            log.warn("사용자 역할 상세 조회 실패 - 사용자ID: {}, 역할코드: {}",
                    userRoleVO.getUserId(), userRoleVO.getRoleCd());
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> selectSysListWithRoleCnt(UserRoleVO userRoleVO) throws Exception {
        log.debug("시스템별 역할 개수 조회 요청 - 사용자ID: {}", userRoleVO.getUserId());
        return userRoleMapper.selectSysListWithRoleCnt(userRoleVO);
    }

    @Override
    public List<Map<String, Object>> selectRoleListBySys(String sysCd) throws Exception {
        log.debug("시스템별 역할 목록 조회 요청 - 시스템코드: {}", sysCd);
        return userRoleMapper.selectRoleListBySys(sysCd);
    }

    @Override
    public List<String> selectUserRoleCodes(UserRoleVO userRoleVO) {
        log.debug("사용자 역할 코드 목록 조회 요청 - 사용자ID: {}", userRoleVO.getUserId());
        return userRoleMapper.selectUserRoleCodes(userRoleVO);
    }

    @Override
    public List<String> selectAutoAssignRoleCodes(UserRoleVO userRoleVO) {
        log.debug("자동 할당 역할 코드 목록 조회 요청 - 사용자ID: {}, 시스템: {}",
                userRoleVO.getUserId(), userRoleVO.getSysCd());
        return userRoleMapper.selectAutoAssignRoleCodes(userRoleVO);
    }

    @Override
    public int selectUserRoleCnt(UserRoleSearchVO searchVO) throws Exception {
        log.debug("사용자 역할 총 개수 조회 요청");
        return userRoleMapper.selectUserRoleCnt(searchVO);
    }

    @Override
    @Transactional
    public Long replaceUserRoles(String userId, String sysCd, List<String> roleCdList,
                                 String aplyBgngYmd, String aplyEndYmd, String rvwOpnnCn, String atchFileId) throws Exception {

        log.info("=== 사용자 역할 전체 교체 시작 ===");
        log.info("대상 사용자: {}, 시스템: {}, 역할 개수: {}, 수정사유: {}", userId, sysCd, roleCdList.size(), rvwOpnnCn);

        String currentUserId = incheon.com.cmm.context.RequestContext.getCurrentUserId();

        // 1. 기존 신청 마스터 만료 처리
        Map<String, Object> expireParams = new java.util.HashMap<>();
        expireParams.put("userId", userId);
        expireParams.put("sysCd", sysCd);
        int expiredCount = userRoleMapper.expireUserRoleAplyMst(expireParams);
        log.info("기존 신청 마스터 만료 완료: {}건", expiredCount);

        // 2. 신청 마스터 생성 (역할이 없으면 만료 상태로 생성)
        Map<String, Object> mstParams = new java.util.HashMap<>();
        mstParams.put("userId", userId);
        mstParams.put("sysCd", sysCd);
        mstParams.put("aplyBgngYmd", aplyBgngYmd);
        mstParams.put("aplyEndYmd", aplyEndYmd);
        mstParams.put("rvwOpnnCn", rvwOpnnCn);
        mstParams.put("atchFileId", atchFileId);
        mstParams.put("isExpired", roleCdList.isEmpty());  // 역할이 없으면 만료 상태로 생성
        userRoleMapper.insertUserRoleAplyMst(mstParams);
        Long aplySn = ((java.math.BigDecimal) mstParams.get("aplySn")).longValue();
        log.info("신청 마스터 생성 완료: APLY_SN={}, 상태={}", aplySn, roleCdList.isEmpty() ? "만료" : "할당");

        // 3. 신청 상세 생성 (루프)
        for (String roleCd : roleCdList) {
            Map<String, Object> dtlParams = new java.util.HashMap<>();
            dtlParams.put("aplySn", aplySn);
            dtlParams.put("userId", userId);
            dtlParams.put("sysCd", sysCd);
            dtlParams.put("roleCd", roleCd);
            userRoleMapper.insertUserRoleAplyDtl(dtlParams);
        }
        log.info("신청 상세 생성 완료: {}건", roleCdList.size());

        // 4. 기존 권한 전체 삭제
        Map<String, Object> deleteParams = new java.util.HashMap<>();
        deleteParams.put("userId", userId);
        deleteParams.put("sysCd", sysCd);
        int deletedCount = userRoleMapper.deleteUserRolesBySystem(deleteParams);
        log.info("기존 권한 삭제 완료: {}건", deletedCount);

        // 5. 새 권한 등록 (루프)
        for (String roleCd : roleCdList) {
            UserRoleVO roleVO = new UserRoleVO();
            roleVO.setUserId(userId);
            roleVO.setRoleCd(roleCd);
            roleVO.setRoleBgngYmd(aplyBgngYmd);
            roleVO.setRoleEndYmd(aplyEndYmd);
            roleVO.setFrstRegId(currentUserId);
            roleVO.setLastMdfcnId(currentUserId);
            roleVO.setSysCd(sysCd);
            userRoleMapper.insertUserRole(roleVO);
        }
        log.info("새 권한 등록 완료: {}건", roleCdList.size());

        log.info("=== 사용자 역할 전체 교체 완료 ===");
        return aplySn;
    }

    @Override
    public List<Map<String, Object>> selectUserRoleAplyDetail(Long aplySn) throws Exception {
        log.debug("신청 상세 역할 목록 조회 요청 - aplySn: {}", aplySn);
        return userRoleMapper.selectUserRoleAplyDetail(aplySn);
    }

    @Override
    public Map<String, Object> selectLatestUserRoleAply(UserRoleVO userRoleVO) throws Exception {
        log.debug("최근 신청 정보 조회 요청 (프리셋용) - 사용자ID: {}, 시스템: {}",
                userRoleVO.getUserId(), userRoleVO.getSysCd());
        return userRoleMapper.selectLatestUserRoleAply(userRoleVO);
    }

    @Override
    public List<Map<String, Object>> selectUserSysRoleDetail(UserRoleVO userRoleVO) throws Exception {
        log.debug("시스템별 보유 역할 상세 조회 요청 - 사용자ID: {}, 시스템: {}",
                userRoleVO.getUserId(), userRoleVO.getSysCd());
        return userRoleMapper.selectUserSysRoleDetail(userRoleVO);
    }
}