package incheon.ags.ias.sys.web;

import incheon.ags.ias.sys.service.SysService;
import incheon.ags.ias.sys.vo.SysSearchVO;
import incheon.ags.ias.sys.vo.SysVO;
import incheon.ags.ias.sys.web.dto.SysRequestDTO;
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 javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 시스템 관리 REST API Controller
 * Base URL: /api/v1/sys
 */
@Tag(name = "시스템 관리 API", description = "시스템 등록, 수정, 삭제, 조회 API")
@Slf4j
@RestController
@RequestMapping("/api/v1/sys")
@RequiredArgsConstructor
@Validated
public class SysApiController {
    private final SysService sysService;

    /* ========================================
     * 시스템 관련 API
     * ======================================== */

    /**
     * 1. 시스템 목록 조회
     * GET /api/v1/sys/list
     */
    @Operation(summary = "시스템 목록 조회", description = "전체 시스템 목록을 조회합니다")
    @GetMapping("/list")
    public ResponseEntity<List<Map<String, Object>>> getSysList() throws Exception {
        SysSearchVO searchVO = new SysSearchVO();
        searchVO.setRecordCountPerPage(1000); // 전체 조회
        searchVO.setFirstIndex(0);
        
        List<Map<String, Object>> result = sysService.selectSysList(searchVO);
        return ResponseEntity.ok(result);
    }

    /**
     * 2. 시스템 상세 조회
     * GET /api/v1/sys/{sysCd}
     */
    @Operation(summary = "시스템 상세 조회", description = "특정 시스템의 상세 정보를 조회합니다")
    @GetMapping("/{sysCd}")
    public ResponseEntity<SysVO> getSysDetail(
            @Parameter(description = "시스템 코드", required = true, example = "SYS001")
            @PathVariable String sysCd) throws Exception {

        SysVO searchVO = new SysVO();
        searchVO.setSysCd(sysCd);
        SysVO result = sysService.selectSysDetail(searchVO);
        
        if (result == null) {
            throw new EntityNotFoundException("시스템");
        }

        return ResponseEntity.ok(result);
    }

    /**
     * 3. 시스템 등록
     * POST /api/v1/sys
     */
    @Operation(summary = "시스템 등록", description = "새로운 시스템을 등록합니다")
    @PostMapping
    public ResponseEntity<DefaultApiResponse<Object>> createSys(
            @Valid @RequestBody SysRequestDTO sysRequestDTO) throws Exception {

        log.info("시스템 등록 요청: {}", sysRequestDTO.toString());

        // 현재 접속한 사용자 ID 설정
        String loginUserId = RequestContext.getCurrentUserId();


        SysVO sysVO = sysRequestDTO.toEntity();
        sysVO.setFrstRegId(loginUserId);
        sysVO.setLastMdfcnId(loginUserId);

        // 중복 체크
        if (sysService.isSysCdDuplicate(sysVO.getSysCd())) {
            throw new BusinessException("이미 존재하는 시스템 코드입니다.");
        }

        int result = sysService.insertSys(sysVO);

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

        log.info("시스템 등록 성공 - 시스템코드: {}", sysVO.getSysCd());
        return ResponseEntity.ok(DefaultApiResponse.success(null, "시스템이 성공적으로 등록되었습니다."));
    }

    /**
     * 4. 시스템 수정
     * PUT /api/v1/sys/{sysCd}
     */
    @Operation(summary = "시스템 수정", description = "기존 시스템 정보를 수정합니다")
    @PutMapping("/{sysCd}")
    public ResponseEntity<DefaultApiResponse<Object>> updateSys(
            @Parameter(description = "시스템 코드", required = true, example = "SYS001")
            @PathVariable String sysCd,
            @Valid @RequestBody SysRequestDTO sysRequestDTO) throws Exception {

        log.info("시스템 수정 요청 - 시스템코드: {}, 데이터: {}", sysCd, sysRequestDTO.toString());

        // 현재 접속한 사용자 ID 설정
        String loginUserId = RequestContext.getCurrentUserId();


        // 시스템 존재 여부 확인
        SysVO searchVO = new SysVO();
        searchVO.setSysCd(sysCd);
        SysVO existingSys = sysService.selectSysDetail(searchVO);

        if (existingSys == null) {
            throw new EntityNotFoundException("시스템");
        }

        // 수정 (PK는 Path Variable에서 가져옴)
        SysVO sysVO = sysRequestDTO.toEntity();
        sysVO.setSysCd(sysCd);
        sysVO.setLastMdfcnId(loginUserId);

        int result = sysService.updateSys(sysVO);

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

        log.info("시스템 수정 성공 - 시스템코드: {}", sysCd);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "시스템이 성공적으로 수정되었습니다."));
    }

    /**
     * 5. 시스템 삭제
     * DELETE /api/v1/sys/{sysCd}
     */
    @Operation(summary = "시스템 삭제", description = "시스템을 삭제합니다")
    @DeleteMapping("/{sysCd}")
    public ResponseEntity<DefaultApiResponse<Object>> deleteSys(
            @Parameter(description = "시스템 코드", required = true, example = "SYS001")
            @PathVariable String sysCd) throws Exception {

        log.info("시스템 삭제 요청 - 시스템코드: {}", sysCd);

        // 시스템 존재 여부 확인
        SysVO searchVO = new SysVO();
        searchVO.setSysCd(sysCd);
        SysVO existingSys = sysService.selectSysDetail(searchVO);

        if (existingSys == null) {
            throw new EntityNotFoundException("시스템");
        }

        SysVO deleteSys = new SysVO();
        deleteSys.setSysCd(sysCd);
        int result = sysService.deleteSys(deleteSys);

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

        log.info("시스템 삭제 성공 - 시스템코드: {}", sysCd);
        return ResponseEntity.ok(DefaultApiResponse.success(null, "시스템이 성공적으로 삭제되었습니다."));
    }

    /* ========================================
     * 전체 조회 및 통계 관련 API
     * ======================================== */

    /**
     * 6. 전체 시스템 목록 조회 (공통코드용)
     * GET /api/v1/sys/all
     */
    @Operation(summary = "전체 시스템 목록 조회", description = "공통코드용 전체 시스템 목록을 조회합니다")
    @GetMapping("/all")
    public ResponseEntity<List<Map<String, Object>>> getAllSysList() throws Exception {
        List<Map<String, Object>> result = sysService.selectAllSysList();
        return ResponseEntity.ok(result);
    }

    /**
     * 7. 시스템별 부서 목록 조회
     * GET /api/v1/sys/dept/list
     */
    @Operation(summary = "시스템별 부서 목록 조회", description = "시스템별 부서 목록을 조회합니다")
    @GetMapping("/dept/list")
    public ResponseEntity<List<Map<String, Object>>> getSysDeptList() throws Exception {
        List<Map<String, Object>> result = sysService.selectSysDeptList();
        return ResponseEntity.ok(result);
    }

    /**
     * 8. 시스템 상태별 통계 조회
     * GET /api/v1/sys/status/count
     */
    @Operation(summary = "시스템 상태별 통계", description = "시스템 상태별 개수를 조회합니다")
    @GetMapping("/status/count")
    public ResponseEntity<Map<String, Object>> getSysStatusCount() throws Exception {
        Map<String, Object> result = sysService.selectSysStatusCnt();
        return ResponseEntity.ok(result);
    }

    /**
     * 9. 시스템별 사용자 수 조회
     * GET /api/v1/sys/user/count
     */
    @Operation(summary = "시스템별 사용자 수", description = "시스템별 사용자 수를 조회합니다")
    @GetMapping("/user/count")
    public ResponseEntity<List<Map<String, Object>>> getUserCountBySys() throws Exception {
        List<Map<String, Object>> result = sysService.selectUserCntBySys();
        return ResponseEntity.ok(result);
    }
}