package incheon.ags.ias.userRole.web;

import incheon.ags.ias.userRole.service.UserRoleService;
import incheon.ags.ias.userRole.vo.UserRoleVO;
import incheon.com.file.service.ComFileService;
import incheon.com.security.util.SecurityUtil;
import incheon.com.security.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequiredArgsConstructor
@Slf4j
public class UserRoleApiController {
    private final UserRoleService userRoleService;
    private final ComFileService comFileService;

    /**
     * 업무관리자 권한 검증 (시스템 코드가 담당 시스템에 포함되는지 확인)
     * @param sysCd 검증할 시스템 코드
     * @return 권한이 있으면 true, 없으면 false
     */
    private boolean hasSystemAuthority(String sysCd) {
        LoginVO loginVO = SecurityUtil.getCurrentUser();
        if (loginVO == null) {
            return false;
        }

        // 통합관리자는 모든 시스템에 대한 권한 있음
        if (loginVO.isSuperAdmin()) {
            return true;
        }

        // 업무관리자는 담당 시스템만 접근 가능
        List<String> adminSysCds = loginVO.getAdminSysCds();
        if (adminSysCds != null && !adminSysCds.isEmpty()) {
            return adminSysCds.contains(sysCd);
        }

        // 그 외 일반 사용자는 권한 없음
        return false;
    }

    /**
     * 시스템별 역할 목록 조회
     * @param sysCd 시스템 코드
     * @param userId 사용자 ID
     * @param mode 조회 모드 (apply: 권한신청용, 그 외: 권한할당용)
     *             - apply: 권한 검증 생략, 프리셋 정보 제외 (일반 사용자 권한 신청용)
     *             - 없거나 다른 값: 기존 로직 (권한 검증 + 프리셋 정보 포함)
     */
    @GetMapping("/ags/ias/userRole/selectRoleListBySys.do")
    @ResponseBody
    public Map<String, Object> selectRoleListBySys(
            @RequestParam("sysCd") String sysCd,
            @RequestParam("userId") String userId,
            @RequestParam(value = "mode", required = false) String mode) {

        Map<String, Object> result = new HashMap<>();
        boolean isApplyMode = "apply".equals(mode);

        try {
            log.info("시스템별 역할 목록 조회 - sysCd: {}, userId: {}, mode: {}", sysCd, userId, mode);

            // 권한 검증: apply 모드가 아닐 때만 검증 (기존 로직 유지)
            if (!isApplyMode && !hasSystemAuthority(sysCd)) {
                log.warn("권한 없음 - sysCd: {}", sysCd);
                result.put("success", false);
                result.put("message", "해당 시스템에 대한 권한이 없습니다.");
                result.put("errorCode", "NO_AUTHORITY");
                return result;
            }

            // 해당 시스템의 모든 역할 조회
            List<Map<String, Object>> roleList = userRoleService.selectRoleListBySys(sysCd);

            // 사용자가 해당 시스템에서 현재 가진 역할 코드 목록 조회
            UserRoleVO userRoleVO = new UserRoleVO();
            userRoleVO.setUserId(userId);
            userRoleVO.setSysCd(sysCd);

            List<String> userRoleCodes = userRoleService.selectUserRoleCodes(userRoleVO);

            // 자동 할당된 역할 코드 목록 조회 (FRST_REG_ID = 'SYSTEM')
            List<String> autoAssignRoleCodes = userRoleService.selectAutoAssignRoleCodes(userRoleVO);

            result.put("success", true);
            result.put("roleList", roleList);
            result.put("userRoleCodes", userRoleCodes);
            result.put("autoAssignRoleCodes", autoAssignRoleCodes);
            result.put("message", "역할 목록 조회 성공");

            // 프리셋 정보: apply 모드가 아닐 때만 조회 (권한 할당용)
            if (!isApplyMode) {
                Map<String, Object> latestAply = userRoleService.selectLatestUserRoleAply(userRoleVO);
                result.put("latestAply", latestAply);
                log.info("조회된 역할 개수: {}, 사용자 보유 역할: {}, 자동할당 역할: {}, 최근신청: {}",
                        roleList.size(), userRoleCodes.size(), autoAssignRoleCodes.size(),
                        latestAply != null ? "있음" : "없음");
            } else {
                log.info("조회된 역할 개수: {}, 사용자 보유 역할: {}, 자동할당 역할: {} (신청 모드)",
                        roleList.size(), userRoleCodes.size(), autoAssignRoleCodes.size());
            }

        } catch (Exception e) {
            log.error("역할 목록 조회 실패", e);
            result.put("success", false);
            result.put("message", "역할 목록 조회에 실패했습니다: " + e.getMessage());
            result.put("errorCode", "QUERY_FAILED");
        }

        return result;
    }

    /**
     * 사용자 역할 전체 교체 (기존 만료 + 신규 할당)
     */
    @PostMapping("/ags/ias/userRole/userRoleModifyAction.do")
    @ResponseBody
    public Map<String, Object> userRoleModifyAction(
            @RequestBody Map<String, Object> params) {

        Map<String, Object> response = new HashMap<>();

        try {
            String userId = (String) params.get("userId");
            String sysCd = (String) params.get("sysCd");
            List<String> roleCdList = (List<String>) params.get("roleCdList");
            String aplyBgngYmd = (String) params.get("aplyBgngYmd");
            String aplyEndYmd = (String) params.get("aplyEndYmd");
            String rvwOpnnCn = (String) params.get("rvwOpnnCn");
            String atchFileId = (String) params.get("atchFileId");

            log.info("사용자 역할 전체 교체 요청 - userId: {}, sysCd: {}, 역할개수: {}, 수정사유: {}",
                    userId, sysCd, roleCdList != null ? roleCdList.size() : 0, rvwOpnnCn);

            // 필수 파라미터 검증
            if (userId == null || userId.isEmpty()) {
                response.put("success", false);
                response.put("message", "사용자 ID는 필수입니다.");
                response.put("errorCode", "MISSING_USER_ID");
                return response;
            }

            if (sysCd == null || sysCd.isEmpty()) {
                response.put("success", false);
                response.put("message", "시스템 코드는 필수입니다.");
                response.put("errorCode", "MISSING_SYS_CD");
                return response;
            }

            // 권한 검증: 해당 시스템에 대한 권한이 있는지 확인
            if (!hasSystemAuthority(sysCd)) {
                log.warn("권한 없음 - userId: {}, sysCd: {}", userId, sysCd);
                response.put("success", false);
                response.put("message", "해당 시스템에 대한 수정 권한이 없습니다.");
                response.put("errorCode", "NO_AUTHORITY");
                return response;
            }

            // 역할 목록이 비어있으면 모든 권한 제거
            if (roleCdList == null) {
                roleCdList = new java.util.ArrayList<>();
            }

            // 전체 교체 실행
            Long aplySn = userRoleService.replaceUserRoles(userId, sysCd, roleCdList, aplyBgngYmd, aplyEndYmd, rvwOpnnCn, atchFileId);

            // 첨부파일 성공처리 (임시 → 정식 전환)
            if (StringUtils.hasText(atchFileId)) {
                comFileService.confirmFiles(atchFileId, "USER_ROLE_APLY_MST");
            }

            response.put("success", true);
            response.put("message", String.format("권한 할당 완료 (%d개 역할)", roleCdList.size()));
            response.put("aplySn", aplySn);
            response.put("roleCount", roleCdList.size());

        } catch (Exception e) {
            log.error("역할 수정 중 오류 발생", e);
            response.put("success", false);
            response.put("message", "역할 수정 중 오류가 발생했습니다: " + e.getMessage());
            response.put("errorCode", "INTERNAL_ERROR");
        }

        return response;
    }

    /**
     * 신청 상세 역할 목록 조회 (팝업용)
     */
    @GetMapping("/ags/ias/userRole/selectUserRoleAplyDetail.do")
    @ResponseBody
    public Map<String, Object> selectUserRoleAplyDetail(@RequestParam("aplySn") Long aplySn) {
        Map<String, Object> response = new HashMap<>();

        try {
            log.info("신청 상세 역할 목록 조회 - aplySn: {}", aplySn);

            List<Map<String, Object>> roleList = userRoleService.selectUserRoleAplyDetail(aplySn);

            response.put("success", true);
            response.put("roleList", roleList);
            response.put("message", "역할 목록 조회 성공");

            log.info("조회된 역할 개수: {}", roleList.size());

        } catch (Exception e) {
            log.error("역할 목록 조회 실패", e);
            response.put("success", false);
            response.put("message", "역할 목록 조회에 실패했습니다: " + e.getMessage());
            response.put("errorCode", "QUERY_FAILED");
        }

        return response;
    }

    /**
     * 사용자 권한 이력 페이징 조회 API (비동기)
     */
    @GetMapping("/ags/ias/userRole/userRoleHistoryList.do")
    @ResponseBody
    public Map<String, Object> userRoleHistoryList(
            @RequestParam("userId") String userId,
            @RequestParam(defaultValue = "1") int page) {

        Map<String, Object> response = new HashMap<>();

        try {
            log.info("사용자 권한 이력 페이징 조회 - userId: {}, page: {}", userId, page);

            // UserRoleVO 설정
            UserRoleVO vo = new UserRoleVO();
            vo.setUserId(userId);
            vo.setPageIndex(page);

            // 권한 필터링: 업무관리자는 담당 시스템만 조회
            LoginVO loginVO = SecurityUtil.getCurrentUser();
            if (loginVO != null && !loginVO.isSuperAdmin()) {
                List<String> adminSysCds = loginVO.getAdminSysCds();
                if (adminSysCds != null && !adminSysCds.isEmpty()) {
                    vo.setSysCdList(adminSysCds);
                    log.info("이력조회 - 업무관리자 필터링 적용 - 시스템 코드: {}", adminSysCds);
                }
            }

            // 페이지네이션 설정
            PaginationInfo paginationInfo = new PaginationInfo();
            paginationInfo.setCurrentPageNo(page);
            paginationInfo.setRecordCountPerPage(vo.getRecordCountPerPage());
            paginationInfo.setPageSize(vo.getPageSize());

            vo.setFirstIndex(paginationInfo.getFirstRecordIndex());
            vo.setLastIndex(paginationInfo.getLastRecordIndex());
            vo.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

            // 데이터 조회
            List<Map<String, Object>> historyList = userRoleService.selectUserRoleHistoryForPaging(vo);
            int totalCount = userRoleService.selectUserRoleHistoryCnt(vo);

            paginationInfo.setTotalRecordCount(totalCount);

            response.put("success", true);
            response.put("data", historyList);
            response.put("paginationInfo", paginationInfo);
            response.put("totalCount", totalCount);
            response.put("message", "조회 성공");

            log.info("조회 결과 - 총 개수: {}, 현재 페이지: {}", totalCount, page);

        } catch (Exception e) {
            log.error("사용자 권한 이력 조회 실패", e);
            response.put("success", false);
            response.put("message", "조회 중 오류가 발생했습니다: " + e.getMessage());
            response.put("errorCode", "QUERY_FAILED");
        }

        return response;
    }
}
