import Incident from "../../Models/DatabaseModels/Incident";
import NotFoundException from "../../Types/Exception/NotFoundException";
import BadDataException from "../../Types/Exception/BadDataException";
import ObjectID from "../../Types/ObjectID";
import IncidentService from "../Services/IncidentService";
import UserMiddleware from "../Middleware/UserAuthorization";
import Response from "../Utils/Response";
import BaseAPI from "./BaseAPI";
import CommonAPI from "./CommonAPI";
import AIService from "../Services/AIService";
import IncidentAIContextBuilder from "../Utils/AI/IncidentAIContextBuilder";
import JSONFunctions from "../../Types/JSONFunctions";
import Permission from "../../Types/Permission";
export default class IncidentAPI extends BaseAPI {
    constructor() {
        var _a, _b, _c;
        super(Incident, IncidentService);
        this.router.get(`${(_a = new this.entityType()
            .getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/postmortem/attachment/:projectId/:incidentId/:fileId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
            try {
                await this.getPostmortemAttachment(req, res);
            }
            catch (err) {
                next(err);
            }
        });
        // Generate postmortem from AI
        this.router.post(`${(_b = new this.entityType()
            .getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/generate-postmortem-from-ai/:incidentId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
            try {
                await this.generatePostmortemFromAI(req, res);
            }
            catch (err) {
                next(err);
            }
        });
        // Generate note from AI
        this.router.post(`${(_c = new this.entityType()
            .getCrudApiPath()) === null || _c === void 0 ? void 0 : _c.toString()}/generate-note-from-ai/:incidentId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
            try {
                await this.generateNoteFromAI(req, res);
            }
            catch (err) {
                next(err);
            }
        });
    }
    async getPostmortemAttachment(req, res) {
        var _a;
        const projectIdParam = req.params["projectId"];
        const incidentIdParam = req.params["incidentId"];
        const fileIdParam = req.params["fileId"];
        if (!projectIdParam || !incidentIdParam || !fileIdParam) {
            throw new NotFoundException("Attachment not found");
        }
        let incidentId;
        let fileId;
        let projectId;
        try {
            incidentId = new ObjectID(incidentIdParam);
            fileId = new ObjectID(fileIdParam);
            projectId = new ObjectID(projectIdParam);
        }
        catch (_b) {
            throw new NotFoundException("Attachment not found");
        }
        const props = await CommonAPI.getDatabaseCommonInteractionProps(req);
        const incident = await this.service.findOneBy({
            query: {
                _id: incidentId,
                projectId,
            },
            select: {
                postmortemAttachments: {
                    _id: true,
                    file: true,
                    fileType: true,
                    name: true,
                },
            },
            props,
        });
        if (!incident) {
            throw new NotFoundException("Attachment not found");
        }
        const attachment = (_a = incident.postmortemAttachments) === null || _a === void 0 ? void 0 : _a.find((file) => {
            const attachmentId = file._id
                ? file._id.toString()
                : file.id
                    ? file.id.toString()
                    : null;
            return attachmentId === fileId.toString();
        });
        if (!attachment || !attachment.file) {
            throw new NotFoundException("Attachment not found");
        }
        Response.setNoCacheHeaders(res);
        return Response.sendFileResponse(req, res, attachment);
    }
    async generatePostmortemFromAI(req, res) {
        var _a;
        const incidentIdParam = req.params["incidentId"];
        if (!incidentIdParam) {
            throw new BadDataException("Incident ID is required");
        }
        let incidentId;
        try {
            incidentId = new ObjectID(incidentIdParam);
        }
        catch (_b) {
            throw new BadDataException("Invalid Incident ID");
        }
        const props = await CommonAPI.getDatabaseCommonInteractionProps(req);
        // Verify user has permission to edit the incident
        const permissions = (_a = props
            .userTenantAccessPermission) === null || _a === void 0 ? void 0 : _a["permissions"];
        const hasPermission = permissions
            ? permissions.some((p) => {
                return (p === Permission.ProjectOwner ||
                    p === Permission.ProjectAdmin ||
                    p === Permission.EditProjectIncident);
            })
            : false;
        if (!hasPermission && !props.isMasterAdmin) {
            throw new BadDataException("You do not have permission to generate postmortem for this incident. You need to have one of these permissions: Project Owner, Project Admin, Edit Project Incident.");
        }
        // Get the template from request body if provided
        const template = JSONFunctions.getJSONValueInPath(req.body, "template");
        // Always include workspace messages for comprehensive context
        const includeWorkspaceMessages = true;
        // Get the incident to verify it exists and get the project ID
        const incident = await this.service.findOneById({
            id: incidentId,
            select: {
                _id: true,
                projectId: true,
            },
            props,
        });
        if (!incident || !incident.projectId) {
            throw new NotFoundException("Incident not found");
        }
        // Build incident context
        const contextData = await IncidentAIContextBuilder.buildIncidentContext({
            incidentId,
            includeWorkspaceMessages,
            workspaceMessageLimit: 500,
        });
        // Format context for postmortem generation
        const aiContext = IncidentAIContextBuilder.formatIncidentContextForPostmortem(contextData, template);
        // Generate postmortem using AIService (handles billing and logging)
        const aiLogRequest = {
            projectId: incident.projectId,
            feature: "Incident Postmortem",
            incidentId: incidentId,
            messages: aiContext.messages,
            maxTokens: 8192,
            temperature: 0.7,
        };
        if (props.userId) {
            aiLogRequest.userId = props.userId;
        }
        const response = await AIService.executeWithLogging(aiLogRequest);
        return Response.sendJsonObjectResponse(req, res, {
            postmortemNote: response.content,
        });
    }
    async generateNoteFromAI(req, res) {
        var _a;
        const incidentIdParam = req.params["incidentId"];
        if (!incidentIdParam) {
            throw new BadDataException("Incident ID is required");
        }
        let incidentId;
        try {
            incidentId = new ObjectID(incidentIdParam);
        }
        catch (_b) {
            throw new BadDataException("Invalid Incident ID");
        }
        const props = await CommonAPI.getDatabaseCommonInteractionProps(req);
        // Verify user has permission to edit the incident
        const permissions = (_a = props
            .userTenantAccessPermission) === null || _a === void 0 ? void 0 : _a["permissions"];
        const hasPermission = permissions
            ? permissions.some((p) => {
                return (p === Permission.ProjectOwner ||
                    p === Permission.ProjectAdmin ||
                    p === Permission.EditProjectIncident ||
                    p === Permission.CreateIncidentInternalNote ||
                    p === Permission.CreateIncidentPublicNote);
            })
            : false;
        if (!hasPermission && !props.isMasterAdmin) {
            throw new BadDataException("You do not have permission to generate notes for this incident.");
        }
        // Get the template and note type from request body
        const template = JSONFunctions.getJSONValueInPath(req.body, "template");
        const noteType = JSONFunctions.getJSONValueInPath(req.body, "noteType") ||
            "internal";
        if (noteType !== "public" && noteType !== "internal") {
            throw new BadDataException("Note type must be 'public' or 'internal'");
        }
        // Always include workspace messages for comprehensive context
        const includeWorkspaceMessages = true;
        // Get the incident to verify it exists and get the project ID
        const incident = await this.service.findOneById({
            id: incidentId,
            select: {
                _id: true,
                projectId: true,
            },
            props,
        });
        if (!incident || !incident.projectId) {
            throw new NotFoundException("Incident not found");
        }
        // Build incident context
        const contextData = await IncidentAIContextBuilder.buildIncidentContext({
            incidentId,
            includeWorkspaceMessages,
            workspaceMessageLimit: 300,
        });
        // Format context for note generation
        const aiContext = IncidentAIContextBuilder.formatIncidentContextForNote(contextData, noteType, template);
        // Generate note using AIService (handles billing and logging)
        const aiLogRequest = {
            projectId: incident.projectId,
            feature: noteType === "public"
                ? "Incident Public Note"
                : "Incident Internal Note",
            incidentId: incidentId,
            messages: aiContext.messages,
            maxTokens: 4096,
            temperature: 0.7,
        };
        if (props.userId) {
            aiLogRequest.userId = props.userId;
        }
        const response = await AIService.executeWithLogging(aiLogRequest);
        return Response.sendJsonObjectResponse(req, res, {
            note: response.content,
        });
    }
}
//# sourceMappingURL=IncidentAPI.js.map