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

import cn.nianxx.thhotel.workflows.reservation.common.request.ManualReviewConversionRequest;
import cn.nianxx.thhotel.workflows.reservation.common.request.ManualReviewResolutionRequest;
import cn.nianxx.thhotel.workflows.reservation.common.request.ReservationOperaSimulationRequest;
import cn.nianxx.thhotel.workflows.reservation.common.request.ReservationTaskPayloadMutationRequest;
import cn.nianxx.thhotel.workflows.reservation.common.result.ManualReviewConversionResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ManualReviewResolutionResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationOperaOperationResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationTaskAuditListResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationTaskDetailResult;
import cn.nianxx.thhotel.workflows.reservation.common.result.ReservationTaskPayloadMutationResult;
import cn.nianxx.thhotel.workflows.reservation.service.ReservationTaskWorkflowService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Reservation 任务 Controller。提供任务详情和人工复核转换接口。
 */
@RestController
@RequestMapping("/api/reservation/tasks")
public class ReservationTaskController {

    private final ReservationTaskWorkflowService taskWorkflowService;

    /**
     * 注入任务工作流服务，Controller 不直接访问 Mapper 或 Repository。
     */
    public ReservationTaskController(ReservationTaskWorkflowService taskWorkflowService) {
        this.taskWorkflowService = taskWorkflowService;
    }

    /**
     * 查询任务详情，返回字段矩阵、当前值和实时可处理状态。
     */
    @GetMapping(value = "/{taskId}", produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationTaskDetailResult detail(@PathVariable Long taskId) {
        return taskWorkflowService.getTaskDetail(taskId);
    }

    /**
     * 将 Fallback / manual_review 任务转换为 New、Update 或 Cancel。
     */
    @PostMapping(
            value = "/{taskId}/manual-review-conversions",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ManualReviewConversionResult convertManualReview(
            @PathVariable Long taskId,
            @RequestBody(required = false) ManualReviewConversionRequest request) {
        return taskWorkflowService.convertManualReviewTask(taskId, request);
    }

    /**
     * 保存任务卡草稿。第一版 field_values 使用矩阵 field_path，不直接生成 OPERA 参数。
     */
    @PutMapping(
            value = "/{taskId}/draft",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationTaskPayloadMutationResult saveDraft(
            @PathVariable Long taskId,
            @RequestBody(required = false) ReservationTaskPayloadMutationRequest request) {
        return taskWorkflowService.saveTaskDraft(taskId, request);
    }

    /**
     * 最终确认任务卡字段；校验通过后任务进入 READY，等待后续 OPERA 阶段处理。
     */
    @PostMapping(
            value = "/{taskId}/confirm",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationTaskPayloadMutationResult confirm(
            @PathVariable Long taskId,
            @RequestBody(required = false) ReservationTaskPayloadMutationRequest request) {
        return taskWorkflowService.confirmTask(taskId, request);
    }

    /**
     * 在原业务任务卡上完成 type-known manual_review 复核，提交字段修正并确认订单归属。
     */
    @PostMapping(
            value = "/{taskId}/manual-review-resolutions",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ManualReviewResolutionResult resolveManualReview(
            @PathVariable Long taskId,
            @RequestBody(required = false) ManualReviewResolutionRequest request) {
        return taskWorkflowService.resolveManualReview(taskId, request);
    }

    /**
     * 执行一条 OPERA 模拟操作；第一版只写入模拟 attempt，不调用真实 OPERA。
     */
    @PostMapping(
            value = "/{taskId}/opera-operations/{operationId}/execute",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationOperaOperationResult executeOperaOperation(
            @PathVariable Long taskId,
            @PathVariable Long operationId,
            @RequestBody(required = false) ReservationOperaSimulationRequest request) {
        return taskWorkflowService.executeOperaOperation(taskId, operationId, request);
    }

    /**
     * 重试失败的 OPERA 模拟操作；重试会追加 attempt 历史。
     */
    @PostMapping(
            value = "/{taskId}/opera-operations/{operationId}/retry",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationOperaOperationResult retryOperaOperation(
            @PathVariable Long taskId,
            @PathVariable Long operationId,
            @RequestBody(required = false) ReservationOperaSimulationRequest request) {
        return taskWorkflowService.retryOperaOperation(taskId, operationId, request);
    }

    /**
     * 查询任务审计流水，供前端后续展示人工确认和 OPERA 模拟操作轨迹。
     */
    @GetMapping(value = "/{taskId}/audits", produces = MediaType.APPLICATION_JSON_VALUE)
    public ReservationTaskAuditListResult listAudits(@PathVariable Long taskId) {
        return taskWorkflowService.listTaskAudits(taskId);
    }
}
