import AIAgentService from "../Services/AIAgentService";
import AIAgentTaskService from "../Services/AIAgentTaskService";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import AIAgentTask from "../../Models/DatabaseModels/AIAgentTask";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import OneUptimeDate from "../../Types/Date";
import AIAgentTaskStatus from "../../Types/AI/AIAgentTaskStatus";
import SortOrder from "../../Types/BaseDatabase/SortOrder";
export default class AIAgentTaskAPI extends BaseAPI {
    constructor() {
        var _a, _b, _c;
        super(AIAgentTask, AIAgentTaskService);
        /*
         * Get the next pending (scheduled) task for processing
         * Validates aiAgentId and aiAgentKey before returning task
         */
        this.router.post(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/get-pending-task`, async (req, res, next) => {
            var _a, _b;
            try {
                const data = req.body;
                /* Validate AI Agent credentials */
                const aiAgent = await this.validateAIAgent(data);
                if (!aiAgent) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid AI Agent ID or AI Agent Key"));
                }
                /* Fetch one scheduled task, sorted by createdAt (oldest first) */
                const task = await AIAgentTaskService.findOneBy({
                    query: {
                        status: AIAgentTaskStatus.Scheduled,
                    },
                    sort: {
                        createdAt: SortOrder.Ascending,
                    },
                    select: {
                        _id: true,
                        projectId: true,
                        taskType: true,
                        metadata: true,
                        createdAt: true,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (!task) {
                    return Response.sendJsonObjectResponse(req, res, {
                        task: null,
                        message: "No pending tasks available",
                    });
                }
                return Response.sendJsonObjectResponse(req, res, {
                    task: {
                        _id: (_a = task._id) === null || _a === void 0 ? void 0 : _a.toString(),
                        projectId: (_b = task.projectId) === null || _b === void 0 ? void 0 : _b.toString(),
                        taskType: task.taskType,
                        metadata: task.metadata,
                        createdAt: task.createdAt,
                    },
                    message: "Task fetched successfully",
                });
            }
            catch (err) {
                next(err);
            }
        });
        /*
         * Get the count of pending (scheduled) tasks for KEDA autoscaling
         * Validates aiAgentId and aiAgentKey before returning count
         */
        this.router.post(`${(_b = new this.entityType().getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/get-pending-task-count`, async (req, res, next) => {
            try {
                const data = req.body;
                /* Validate AI Agent credentials */
                const aiAgent = await this.validateAIAgent(data);
                if (!aiAgent) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid AI Agent ID or AI Agent Key"));
                }
                /* Count scheduled tasks */
                const count = await AIAgentTaskService.countBy({
                    query: {
                        status: AIAgentTaskStatus.Scheduled,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                return Response.sendJsonObjectResponse(req, res, {
                    count: count,
                    message: "Pending task count fetched successfully",
                });
            }
            catch (err) {
                next(err);
            }
        });
        /*
         * Update task status (InProgress, Completed, Error)
         * Validates aiAgentId and aiAgentKey before updating
         */
        this.router.post(`${(_c = new this.entityType().getCrudApiPath()) === null || _c === void 0 ? void 0 : _c.toString()}/update-task-status`, async (req, res, next) => {
            try {
                const data = req.body;
                /* Validate AI Agent credentials */
                const aiAgent = await this.validateAIAgent(data);
                if (!aiAgent) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Invalid AI Agent ID or AI Agent Key"));
                }
                /* Validate required fields */
                if (!data["taskId"]) {
                    return Response.sendErrorResponse(req, res, new BadDataException("taskId is required"));
                }
                if (!data["status"]) {
                    return Response.sendErrorResponse(req, res, new BadDataException("status is required"));
                }
                const taskId = new ObjectID(data["taskId"]);
                const status = data["status"];
                const statusMessage = data["statusMessage"];
                /* Validate status value */
                const validStatuses = [
                    AIAgentTaskStatus.InProgress,
                    AIAgentTaskStatus.Completed,
                    AIAgentTaskStatus.Error,
                ];
                if (!validStatuses.includes(status)) {
                    return Response.sendErrorResponse(req, res, new BadDataException(`Invalid status. Must be one of: ${validStatuses.join(", ")}`));
                }
                /* Check if task exists */
                const existingTask = await AIAgentTaskService.findOneById({
                    id: taskId,
                    select: {
                        _id: true,
                        status: true,
                    },
                    props: {
                        isRoot: true,
                    },
                });
                if (!existingTask) {
                    return Response.sendErrorResponse(req, res, new BadDataException("Task not found"));
                }
                /* Update the task based on status */
                if (status === AIAgentTaskStatus.InProgress) {
                    await AIAgentTaskService.updateOneById({
                        id: taskId,
                        data: Object.assign(Object.assign(Object.assign({ status: status }, (aiAgent.id && { aiAgentId: aiAgent.id })), { startedAt: OneUptimeDate.getCurrentDate() }), (statusMessage && { statusMessage: statusMessage })),
                        props: {
                            isRoot: true,
                        },
                    });
                }
                else if (status === AIAgentTaskStatus.Completed ||
                    status === AIAgentTaskStatus.Error) {
                    await AIAgentTaskService.updateOneById({
                        id: taskId,
                        data: Object.assign({ status: status, completedAt: OneUptimeDate.getCurrentDate() }, (statusMessage && { statusMessage: statusMessage })),
                        props: {
                            isRoot: true,
                        },
                    });
                }
                return Response.sendJsonObjectResponse(req, res, {
                    taskId: taskId.toString(),
                    status: status,
                    message: "Task status updated successfully",
                });
            }
            catch (err) {
                next(err);
            }
        });
    }
    /*
     * Validate AI Agent credentials from request body
     * Returns AIAgent if valid, null otherwise
     */
    async validateAIAgent(data) {
        if (!data["aiAgentId"] || !data["aiAgentKey"]) {
            return null;
        }
        const aiAgentId = new ObjectID(data["aiAgentId"]);
        const aiAgentKey = data["aiAgentKey"];
        const aiAgent = await AIAgentService.findOneBy({
            query: {
                _id: aiAgentId.toString(),
                key: aiAgentKey,
            },
            select: {
                _id: true,
            },
            props: {
                isRoot: true,
            },
        });
        return aiAgent;
    }
}
//# sourceMappingURL=AIAgentTaskAPI.js.map