package cn.nianxx.thhotel.workflows.reservation.control;

import cn.nianxx.thhotel.integrations.ai.superagent.service.impl.SuperAgentTaskResultException;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationAiQueryErrorResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationAiQueryResponse;
import cn.nianxx.thhotel.workflows.reservation.service.impl.ReservationAiQueryException;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Map;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * SuperAgent 查询接口异常处理。统一返回 success=false，不暴露内部堆栈或敏感上下文。
 */
@RestControllerAdvice(assignableTypes = ReservationAiQueryController.class)
public class ReservationAiQueryControllerAdvice {

    /**
     * 处理查询服务抛出的受控参数错误和对象不存在错误。
     */
    @ExceptionHandler(ReservationAiQueryException.class)
    public ResponseEntity<ReservationAiQueryResponse<Object>> handleAiQueryException(
            ReservationAiQueryException exception,
            HttpServletRequest request) {
        return failure(
                exception.getStatus().value(),
                request,
                exception.getErrorCode(),
                exception.getMessage(),
                exception.getDetails());
    }

    /**
     * 处理 HMAC、时间窗口、nonce 和请求体大小等协议层错误。
     */
    @ExceptionHandler(SuperAgentTaskResultException.class)
    public ResponseEntity<ReservationAiQueryResponse<Object>> handleSecurityException(
            SuperAgentTaskResultException exception,
            HttpServletRequest request) {
        return failure(
                exception.getStatus().value(),
                request,
                exception.getErrorCode(),
                exception.getMessage(),
                Map.of());
    }

    /**
     * 处理缺少 X-Request-Id 等必要请求头的错误。
     */
    @ExceptionHandler(MissingRequestHeaderException.class)
    public ResponseEntity<ReservationAiQueryResponse<Object>> handleMissingHeader(
            MissingRequestHeaderException exception,
            HttpServletRequest request) {
        return failure(
                400,
                request,
                "REQUEST_HEADER_REQUIRED",
                exception.getHeaderName() + " 请求头不能为空",
                Map.of());
    }

    /**
     * 构造查询接口统一失败响应，异常路径只返回安全错误码和必要追踪字段。
     */
    private ResponseEntity<ReservationAiQueryResponse<Object>> failure(
            int status,
            HttpServletRequest request,
            String code,
            String message,
            Map<String, Object> details) {
        return ResponseEntity.status(status)
                .body(ReservationAiQueryResponse.failure(
                        firstHeader(request, "X-TH-Hotel-Request-Id", "X-Request-Id"),
                        firstHeader(request, "X-TH-Hotel-AI-Trace-Id", "X-AI-Trace-Id"),
                        new ReservationAiQueryErrorResult(code, message, details)));
    }

    /**
     * 读取第一个非空 Header，兼容旧查询接口追踪头和新的 SuperAgent 统一追踪头。
     */
    private String firstHeader(HttpServletRequest request, String first, String second) {
        String firstValue = request.getHeader(first);
        if (firstValue != null && !firstValue.isBlank()) {
            return firstValue;
        }
        String secondValue = request.getHeader(second);
        if (secondValue != null && !secondValue.isBlank()) {
            return secondValue;
        }
        return null;
    }
}
