package incheon.com.weblog.web;

import incheon.com.cmm.context.RequestContext;
import incheon.com.security.vo.LoginVO;
import incheon.com.weblog.service.WeblogService;
import incheon.com.weblog.vo.WeblogVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 지도출력 로그 API 컨트롤러
 *
 * <p>지도 PDF 저장, 이미지 저장, 인쇄 기능 사용 시 웹 로그 기록용</p>
 *
 * @author Claude Code
 * @since 2025.12.23
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/com/log")
@Tag(name = "지도출력 로그", description = "지도 출력(PDF/이미지/인쇄) 로그 API")
public class MapOutputLogApiController {

    private final WeblogService weblogService;

    /**
     * 지도출력 로그 기록
     *
     * @param request HTTP 요청
     * @param dto     로그 옵션 (sysCd, menuCd - 선택)
     * @return 성공 응답
     */
    @PostMapping("/mapOutput")
    @Operation(summary = "지도출력 로그", description = "지도 PDF/이미지 저장, 인쇄 시 호출하여 웹 로그에 기록")
    public ResponseEntity<Map<String, Object>> logMapOutput(
            HttpServletRequest request,
            @RequestBody(required = false) MapOutputLogRequest dto) {

        try {
            WeblogVO vo = new WeblogVO();

            // 요청 정보
            vo.setDmndUrlAddr("/api/v1/com/log/mapOutput");
            vo.setDmndMethCd("POST");
            vo.setCntnDt(LocalDateTime.now());
            vo.setCntnIp(request.getRemoteAddr());
            vo.setSesionId(request.getSession(false) != null ? request.getSession().getId() : "");

            // User-Agent 및 디바이스 타입
            String userAgent = request.getHeader("User-Agent");
            vo.setUserAgen(userAgent);
            vo.setDeviceTypeNm(userAgent != null && userAgent.toLowerCase().contains("mobi") ? "MOBILE" : "PC");
            vo.setDmndRefe(request.getHeader("Referer"));

            // 사용자 정보 (RequestContext에서)
            LoginVO loginVO = RequestContext.getCurrentUser();
            if (loginVO != null) {
                vo.setUserId(loginVO.getUserId());
                vo.setUserNm(loginVO.getUserNm());
                vo.setDeptCd(loginVO.getDeptCd());
                // [고객요청] 부서명(변별성 부족)을 부서전체명으로 변경
                vo.setDeptNm(loginVO.getDeptWholNm());
            }

            // 시스템/메뉴 코드 (옵션으로 전달받은 값 우선, 없으면 RequestContext)
            if (dto != null && dto.getSysCd() != null && !dto.getSysCd().isEmpty()) {
                vo.setSysCd(dto.getSysCd());
            } else {
                vo.setSysCd(RequestContext.getCurrentSysCd());
            }

            if (dto != null && dto.getMenuCd() != null && !dto.getMenuCd().isEmpty()) {
                vo.setMenuCd(dto.getMenuCd());
            } else {
                vo.setMenuCd(RequestContext.getCurrentMenuCd());
            }

            // 시스템/메뉴명은 RequestContext에서
            vo.setSysNm(RequestContext.getCurrentSysNm());
            vo.setMenuNm(RequestContext.getCurrentMenuNm());

            // 응답 상태 및 처리 시간
            vo.setRspnsStts(200);
            vo.setPrcsHr(0L);

            // 로그 저장
            weblogService.insertWebLog(vo);

            log.debug("지도출력 로그 기록 완료 - sysCd: {}, menuCd: {}", vo.getSysCd(), vo.getMenuCd());

        } catch (Exception e) {
            log.error("지도출력 로그 기록 실패", e);
            // 로그 실패는 사용자에게 영향 주지 않음
        }

        return ResponseEntity.ok(Map.of(
            "code", 200,
            "message", "OK"
        ));
    }

    /**
     * 지도출력 로그 요청 DTO
     */
    @Getter
    @Setter
    public static class MapOutputLogRequest {
        private String sysCd;
        private String menuCd;
    }
}
