package com.eactive.eai.rms.onl.apim.obp;

import com.eactive.eai.rms.onl.common.exception.BizException;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.onl.apim.common.BaseRestController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.List;

/**
 * ObpGwMetric REST Controller
 * API Gateway 시간별 거래량 지표 조회 API
 *
 * @see BaseRestController 세션 체크 우회 및 JSON 유틸리티 제공
 */
@Controller
public class ObpGwMetricController extends BaseRestController {

    private static final Logger log = LoggerFactory.getLogger(ObpGwMetricController.class);

    private static final DateTimeFormatter PATH_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm:ss");

    private static final DateTimeFormatter QUERY_PARAM_FORMATTER =
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    private final ObpGwMetricManService obpGwMetricManService;

    public ObpGwMetricController(ObpGwMetricManService obpGwMetricManService) {
        this.obpGwMetricManService = obpGwMetricManService;
    }

    /**
     * 특정 시간대 이후의 GwMetric 데이터 조회 (v2)
     *
     * @param timeslice    조회 시작 시간대 (형식: yyyyMMddHHmmss)
     * @param providerCode Provider 코드 (KJB만 허용, 대소문자 무시)
     * @param pretty       true면 JSON 들여쓰기 적용
     * @return JSON Array (해당 시간대 이후의 모든 지표)
     */
    @RequestMapping(
        value = "/metrics/afterTimeslice/{timeslice}/{providerCode}",
        method = RequestMethod.GET,
        produces = JSON_CONTENT_TYPE
    )
    @ResponseBody
    public String getGwMetricsAfterTimeslice(
            @PathVariable("timeslice") String timeslice,
            @PathVariable("providerCode") String providerCode,
            @RequestParam(value = "pretty", required = false) Boolean pretty) {

        log.debug("GwMetric after-timeslice 조회 요청: timeslice={}, providerCode={}, pretty={}",
                timeslice, providerCode, pretty);
        long startTime = System.currentTimeMillis();

        try {
            // 1. providerCode 검증
            ProviderCodeValidator.validateProviderCode(providerCode);

            // 2. timeslice 파싱 (새 형식: yyyyMMddHHmmss)
            LocalDateTime targetTime;
            try {
                targetTime = LocalDateTime.parse(timeslice, QUERY_PARAM_FORMATTER);
            } catch (DateTimeParseException e) {
                throw new BizException(
                    String.format("Invalid timeslice format. Expected 'yyyyMMddHHmmss', got: %s", timeslice), e);
            }

            // 3. 시간을 정각으로 truncate
            LocalDateTime timesliceHour = targetTime.withMinute(0).withSecond(0).withNano(0);

            // 4. 데이터소스 설정 (MONITORING)
            DataSourceContextHolder.setDataSourceType(
                    DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING));

            // 5. 데이터 조회
            List<ObpGwMetricDTO> metrics = obpGwMetricManService.findByTimesliceAfter(timesliceHour);

            // 6. JSON 변환
            String json = toJson(metrics, pretty);

            long elapsed = System.currentTimeMillis() - startTime;
            log.info("GwMetric after-timeslice 조회 완료 (v2): timeslice={}, providerCode={}, count={}, size={}, elapsed={}ms",
                    timeslice, providerCode, metrics.size(), getFormattedJsonSize(json), elapsed);

            return json;

        } catch (BizException e) {
            throw e;
        } catch (Exception e) {
            log.error("GwMetric after-timeslice 조회 실패 (v2): timeslice={}, providerCode={}",
                    timeslice, providerCode, e);
            throw new BizException("Failed to retrieve metrics: " + e.getMessage(), e);
        }
    }
}
