package incheon.ags.ias.user.web;

import incheon.ags.ias.tmprUserAuthrt.service.TmprUserAuthrtService;
import incheon.ags.ias.user.service.UserService;
import incheon.ags.ias.user.vo.UserSearchVO;
import incheon.ags.ias.user.vo.UserVO;
import incheon.ags.ias.user.web.dto.UserRequestDTO;
import incheon.com.cmm.api.DefaultApiResponse;
import incheon.com.cmm.context.RequestContext;
import incheon.com.cmm.exception.BusinessException;
import incheon.com.cmm.exception.EntityNotFoundException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 사용자 관리 REST API Controller
 * Base URL: /api/v1/user
 */
@Tag(name = "사용자 관리 API", description = "사용자 등록, 수정, 삭제, 조회 API")
@Slf4j
@RestController
@RequestMapping("/api/v1/user")
@RequiredArgsConstructor
@Validated
public class UserApiController {
    private final UserService userService;
    private final TmprUserAuthrtService tmprUserAuthrtService;

    /* ========================================
     * 사용자 관련 API
     * ======================================== */

    /**
     * 1. 사용자 목록 조회 (페이징 지원)
     * GET /api/v1/user/list
     */
    @Operation(summary = "사용자 목록 조회", description = "사용자 목록을 페이징하여 조회합니다")
    @GetMapping("/list")
    public ResponseEntity<DefaultApiResponse<Map<String, Object>>> getUserList(
            @Parameter(description = "페이지 번호", example = "1")
            @RequestParam(defaultValue = "1") int page,
            @Parameter(description = "페이지당 레코드 수", example = "10")
            @RequestParam(defaultValue = "10") int recordCountPerPage,
            @Parameter(description = "검색 키워드 (사용자명, ID, 부서명)")
            @RequestParam(required = false) String searchKeyword,
            @Parameter(description = "부서코드 (부서별 사용자 조회)")
            @RequestParam(required = false) String deptCd) throws Exception {

        log.debug("사용자 목록 조회 - page: {}, recordCountPerPage: {}, searchKeyword: {}, deptCd: {}", page, recordCountPerPage, searchKeyword, deptCd);

        UserSearchVO searchVO = new UserSearchVO();
        searchVO.setUserNm(searchKeyword);  // userNm 필드로 통합 검색 (Mapper에서 OR 조건)
        searchVO.setDeptCd(deptCd);  // 부서코드 필터

        // 1. 총 개수 조회
        int totalCount = userService.selectUserCnt(searchVO);

        // 2. PaginationInfo 설정
        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(page);
        paginationInfo.setRecordCountPerPage(recordCountPerPage);
        paginationInfo.setPageSize(searchVO.getPageSize());  // 기본값 10
        paginationInfo.setTotalRecordCount(totalCount);

        // 3. 페이징 파라미터 설정 (firstIndex 계산)
        searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
        searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

        // 4. 데이터 조회
        List<Map<String, Object>> list = userService.selectUserList(searchVO);

        // 5. 응답 구성
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("list", list);
        resultMap.put("paginationInfo", paginationInfo);
        resultMap.put("totalCount", totalCount);

        return ResponseEntity.ok(DefaultApiResponse.success(resultMap));
    }

    /**
     * 2. 사용자 상세 조회
     * GET /api/v1/user/{userId}
     */
    @Operation(summary = "사용자 상세 조회", description = "특정 사용자의 상세 정보를 조회합니다")
    @GetMapping("/{userId}")
    public ResponseEntity<UserVO> getUserDetail(
            @Parameter(description = "사용자 ID", required = true, example = "admin")
            @PathVariable String userId) throws Exception {

        UserVO searchVO = new UserVO();
        searchVO.setUserId(userId);
        UserVO result = userService.selectUserDetail(searchVO);
        
        if (result == null) {
            throw new EntityNotFoundException("사용자");
        }

        return ResponseEntity.ok(result);
    }

    /**
     * 3. 사용자 등록
     * POST /api/v1/user
     */
    @Operation(summary = "사용자 등록", description = "새로운 사용자를 등록합니다")
    @PostMapping
    public ResponseEntity<DefaultApiResponse<Object>> createUser(
            @Valid @RequestBody UserRequestDTO userRequestDTO) throws Exception {

        log.info("사용자 등록 요청: {}", userRequestDTO.toString());

        // RequestContext에서 현재 사용자 ID 조회
        String loginUserId = RequestContext.getCurrentUserId();


        UserVO userVO = userRequestDTO.toEntity();
        userVO.setFrstRegId(loginUserId);
        userVO.setLastMdfcnId(loginUserId);

        // 중복 체크
        if (userService.isUserIdDuplicate(userVO.getUserId())) {
            throw new BusinessException("이미 존재하는 사용자 ID입니다.");
        }

        int result = userService.insertUser(userVO);

        if (result <= 0) {
            throw new BusinessException("사용자 등록에 실패했습니다.");
        }

        log.info("사용자 등록 성공 - 사용자ID: {}", userVO.getUserId());
        return ResponseEntity.ok(DefaultApiResponse.success(null, "사용자가 성공적으로 등록되었습니다."));
    }

    /**
     * 4. 사용자 수정
     * PUT /api/v1/user/{userId}
     */
    @Operation(summary = "사용자 수정", description = "기존 사용자 정보를 수정합니다")
    @PutMapping("/{userId}")
    public ResponseEntity<DefaultApiResponse<Object>> updateUser(
            @Parameter(description = "사용자 ID", required = true, example = "admin")
            @PathVariable String userId,
            @Valid @RequestBody UserRequestDTO userRequestDTO) throws Exception {

        log.info("사용자 수정 요청 - 사용자ID: {}, 데이터: {}", userId, userRequestDTO.toString());

        // RequestContext에서 현재 사용자 ID 조회
        String loginUserId = RequestContext.getCurrentUserId();


        // 사용자 존재 여부 확인
        UserVO searchVO = new UserVO();
        searchVO.setUserId(userId);
        UserVO existingUser = userService.selectUserDetail(searchVO);

        if (existingUser == null) {
            throw new EntityNotFoundException("사용자");
        }

        // 수정 (PK는 Path Variable에서 가져옴)
        UserVO userVO = userRequestDTO.toEntity();
        userVO.setUserId(userId);
        userVO.setLastMdfcnId(loginUserId);

        int result = userService.updateUser(userVO);

        if (result <= 0) {
            throw new BusinessException("사용자 수정에 실패했습니다.");
        }

        log.info("사용자 수정 성공 - 사용자ID: {}", userId);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "사용자가 성공적으로 수정되었습니다."));
    }

    /**
     * 5. 사용자 삭제
     * DELETE /api/v1/user/{userId}
     */
    @Operation(summary = "사용자 삭제", description = "사용자를 삭제합니다 (관련 권한도 함께 삭제)")
    @DeleteMapping("/{userId}")
    public ResponseEntity<DefaultApiResponse<Object>> deleteUser(
            @Parameter(description = "사용자 ID", required = true, example = "admin")
            @PathVariable String userId) throws Exception {

        log.info("사용자 삭제 요청 - 사용자ID: {}", userId);

        // 사용자 존재 여부 확인
        UserVO searchVO = new UserVO();
        searchVO.setUserId(userId);
        UserVO existingUser = userService.selectUserDetail(searchVO);

        if (existingUser == null) {
            throw new EntityNotFoundException("사용자");
        }

        // 1. 사용자별 모든 임시 권한 삭제 (메뉴 권한, 시스템 권한, 임시 권한)
        int authrtDeleteCount = 0;
        try {
            authrtDeleteCount = tmprUserAuthrtService.deleteAllTmprUserAuthrtByUserId(userId);
            log.info("사용자 권한 삭제 완료 - 사용자ID: {}, 삭제된 권한 수: {}", userId, authrtDeleteCount);
        } catch (Exception e) {
            log.warn("사용자 권한 삭제 중 오류 발생 - 사용자ID: {}, 오류: {}", userId, e.getMessage());
            // 권한 삭제 실패해도 사용자 삭제는 계속 진행
        }

        // 2. 사용자 삭제
        UserVO deleteUser = new UserVO();
        deleteUser.setUserId(userId);
        int result = userService.deleteUser(deleteUser);

        if (result <= 0) {
            throw new BusinessException("사용자 삭제에 실패했습니다.");
        }

        log.info("사용자 삭제 성공 - 사용자ID: {}, 삭제된 권한 수: {}", userId, authrtDeleteCount);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "사용자와 관련된 모든 권한이 삭제되었습니다."));
    }

    /* ========================================
     * 부서/직급 관련 API
     * ======================================== */

    /**
     * 6. 부서 목록 조회
     * GET /api/v1/user/dept/list
     */
    @Operation(summary = "부서 목록 조회", description = "전체 부서 목록을 조회합니다")
    @GetMapping("/dept/list")
    public ResponseEntity<List<Map<String, Object>>> getDeptList() throws Exception {
        List<Map<String, Object>> result = userService.deptList();
        return ResponseEntity.ok(result);
    }

    /**
     * 7. 직급 목록 조회
     * GET /api/v1/user/jbgd/list
     */
    @Operation(summary = "직급 목록 조회", description = "전체 직급 목록을 조회합니다")
    @GetMapping("/jbgd/list")
    public ResponseEntity<List<Map<String, Object>>> getJbgdList() throws Exception {
        List<Map<String, Object>> result = userService.jbgdList();
        return ResponseEntity.ok(result);
    }

    /**
     * 8. 사용자 상태별 통계 조회
     * GET /api/v1/user/status/count
     */
    @Operation(summary = "사용자 상태별 통계", description = "사용자 상태별 개수를 조회합니다")
    @GetMapping("/status/count")
    public ResponseEntity<Map<String, Object>> getUserStatusCount() throws Exception {
        Map<String, Object> result = userService.selectUserStatusCnt();
        return ResponseEntity.ok(result);
    }

    /**
     * 9. 부서별 사용자 수 조회
     * GET /api/v1/user/dept/count
     */
    @Operation(summary = "부서별 사용자 수", description = "부서별 사용자 수를 조회합니다")
    @GetMapping("/dept/count")
    public ResponseEntity<List<Map<String, Object>>> getUserCountByDept() throws Exception {
        List<Map<String, Object>> result = userService.selectUserCntByDept();
        return ResponseEntity.ok(result);
    }
}