package cn.nianxx.thhotel.integrations.ai.superagent.control;

import cn.nianxx.thhotel.integrations.ai.superagent.common.request.SuperAgentTaskResultSecurityRequest;
import cn.nianxx.thhotel.integrations.ai.superagent.service.SuperAgentTaskResultSecurityService;
import cn.nianxx.thhotel.integrations.ai.superagent.service.impl.SuperAgentTaskResultException;
import cn.nianxx.thhotel.integrations.ai.superagent.service.impl.SuperAgentTaskResultProperties;
import cn.nianxx.thhotel.platform.hotel.service.HotelContextService;
import cn.nianxx.thhotel.workflows.reservation.common.result.SuperAgentTaskResultResponse;
import cn.nianxx.thhotel.workflows.reservation.service.ReservationAiTaskIntakeService;
import java.nio.charset.StandardCharsets;
import org.springframework.http.HttpStatus;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * SuperAgent 任务结果入站接口。Controller 只处理外部协议、安全校验和请求分发。
 */
@RestController
@RequestMapping("/api/integrations/superagent/task-results")
public class SuperAgentTaskResultController {

    private static final String REQUEST_PATH = "/api/integrations/superagent/task-results";

    private final SuperAgentTaskResultSecurityService securityService;
    private final SuperAgentTaskResultProperties properties;
    private final HotelContextService hotelContextService;
    private final ReservationAiTaskIntakeService intakeService;

    /**
     * 注入 SuperAgent 安全服务和 Reservation 接收服务，避免 Controller 直接访问业务持久化层。
     */
    public SuperAgentTaskResultController(
            SuperAgentTaskResultSecurityService securityService,
            SuperAgentTaskResultProperties properties,
            HotelContextService hotelContextService,
            ReservationAiTaskIntakeService intakeService) {
        this.securityService = securityService;
        this.properties = properties;
        this.hotelContextService = hotelContextService;
        this.intakeService = intakeService;
    }

    /**
     * 接收 SuperAgent AI 任务结果，支持 JSON 和 S000/S999 文本结果；HMAC 始终基于原始请求体校验。
     */
    @PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<SuperAgentTaskResultResponse> accept(
            @RequestBody(required = false) String rawBody,
            @RequestHeader(name = "Content-Type", required = false) String contentType,
            @RequestHeader(name = "X-TH-Hotel-SuperAgent-Client-Id", required = false) String clientId,
            @RequestHeader(name = "X-TH-Hotel-SuperAgent-Timestamp", required = false) String timestamp,
            @RequestHeader(name = "X-TH-Hotel-SuperAgent-Nonce", required = false) String nonce,
            @RequestHeader(name = "X-TH-Hotel-SuperAgent-Signature", required = false) String signature,
            @RequestHeader(name = "X-TH-Hotel-Request-Id", required = false) String requestId) {
        String requestBody = rawBody == null ? "" : rawBody;
        rejectBodyWhenTooLarge(requestBody);
        rejectUnsupportedContentType(contentType);
        securityService.verify(new SuperAgentTaskResultSecurityRequest(
                "POST",
                REQUEST_PATH,
                clientId,
                timestamp,
                nonce,
                signature,
                requestBody
        ));
        SuperAgentTaskResultResponse response = intakeService.accept(
                requestBody,
                clientId,
                requestId,
                hotelContextService.resolveSystemHotelId());
        HttpStatus status = response.idempotentReplay() ? HttpStatus.OK : HttpStatus.CREATED;
        return ResponseEntity.status(status).body(response);
    }

    /**
     * 仅允许 JSON 结构化任务或 text/plain 入口结果文本，避免其他媒体类型误入业务解析。
     */
    private void rejectUnsupportedContentType(String contentType) {
        String rawContentType = contentType == null ? "" : contentType.trim();
        if (rawContentType.isEmpty()) {
            throw unsupportedContentType();
        }
        MediaType mediaType;
        try {
            mediaType = MediaType.parseMediaType(rawContentType);
        } catch (InvalidMediaTypeException exception) {
            throw unsupportedContentType();
        }
        if (!MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)
                && !MediaType.TEXT_PLAIN.isCompatibleWith(mediaType)) {
            throw unsupportedContentType();
        }
    }

    /**
     * 构造统一的 Content-Type 不支持错误，避免把外部原始 Header 写入响应。
     */
    private SuperAgentTaskResultException unsupportedContentType() {
        return new SuperAgentTaskResultException(
                HttpStatus.UNSUPPORTED_MEDIA_TYPE,
                "REQUEST_CONTENT_TYPE_UNSUPPORTED",
                "Content-Type 仅支持 application/json 或 text/plain。");
    }

    /**
     * 在解析 JSON 和校验 Header 之前限制请求体大小，避免超限请求进入后续处理。
     */
    private void rejectBodyWhenTooLarge(String rawBody) {
        long maxBodyBytes = properties.getMaxBodyBytes();
        int actualBytes = rawBody.getBytes(StandardCharsets.UTF_8).length;
        if (maxBodyBytes >= 0 && actualBytes > maxBodyBytes) {
            throw new SuperAgentTaskResultException(
                    HttpStatus.PAYLOAD_TOO_LARGE,
                    "REQUEST_BODY_TOO_LARGE",
                    "请求体超过允许大小。");
        }
    }
}
