"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.jsonParser = void 0;
const express_1 = __importDefault(require("express"));
const path_1 = __importDefault(require("path"));
const promises_1 = require("node:fs/promises");
const body_parser_1 = __importDefault(require("body-parser"));
const websocket_1 = require("../websocket");
const workspace_1 = require("../controllers/workspace");
const cliconfig_1 = __importStar(require("../database/cliconfig"));
// import { prompt as promptOpenAI } from "../controllers/openaiAgent";
// import { promptWithoutChatSave as promptClaudeByPlanner } from "../controllers/claudeAgent";
// import { prompt as promptClaude } from "../controllers/claudeAgent";
const pluginAgent_1 = require("../controllers/agents/pluginAgent");
// import { AppPlannerAgent } from "../controllers/agents/appPlannerAgent";
// import { prompt as webPromptOpenAI } from '../controllers/webReactOpenAiAgent';
// import { prompt as webPromptClaude } from '../controllers/webReactClaudeAgent';
const baseAgent_1 = require("../controllers/agents/baseAgent");
const compiler_1 = require("../controllers/compiler");
const js_sha256_1 = require("js-sha256");
const logger_1 = require("../utils/logger");
const chalk_1 = __importDefault(require("chalk"));
const apptileServerTokenManagement_1 = require("../services/apptileServerTokenManagement");
const baseAgent_2 = require("../controllers/agents/baseAgent");
const chat_1 = __importDefault(require("../models/chat"));
const chatmessage_1 = __importDefault(require("../models/chatmessage"));
const sequelize_1 = require("sequelize");
const appPlannerAgent_1 = require("../controllers/agents/appPlannerAgent");
exports.jsonParser = body_parser_1.default.json({ limit: "50mb" });
const router = express_1.default.Router();
const pluginAgent = new pluginAgent_1.PluginAgent();
const plannerAgent = new appPlannerAgent_1.AppPlannerAgent();
const isPostgresEnabled = process.env.ENABLE_POSTGRES == 'true';
function listPluginNames(repoPath) {
    return __awaiter(this, void 0, void 0, function* () {
        const pluginsRoot = path_1.default.resolve(repoPath, "remoteCode/plugins");
        try {
            const contents = yield (0, promises_1.readdir)(pluginsRoot, { withFileTypes: true });
            const dirs = contents
                .filter((it) => it.isDirectory())
                .map((it) => it.name);
            return dirs;
        }
        catch (err) {
            if ((err === null || err === void 0 ? void 0 : err.code) === "ENOENT") {
            }
            else {
                console.error("Unhandelable error", err);
                throw err;
            }
            return [];
        }
    });
}
router.get("/:appid/list", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            try {
                const pluginNames = yield listPluginNames(openedApp.repoPath);
                res.json(pluginNames);
            }
            catch (err) {
                next(err);
            }
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appid/create", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            const body = {
                __LABEL_PREFIX__: req.body.labelPrefix,
                __LISTING_NAME__: req.body.listingName,
                __DISPLAY_DESCRIPTION__: req.body.displayDescription,
                __LISTING_ICON__: req.body.listingIcon,
                __PLUGIN_REGISTRY_NAME__: req.body.pluginRegistryName,
                __PLUGIN_NAME__: req.body.listingName,
            };
            const name = req.body.pluginRegistryName.toLowerCase();
            const pluginRoot = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins`, name);
            try {
                yield (0, promises_1.mkdir)(path_1.default.resolve(pluginRoot, "source"), { recursive: true });
            }
            catch (err) {
                if ((err === null || err === void 0 ? void 0 : err.code) !== "EEXIST") {
                    console.error("Unhandelable error", err);
                    next(err);
                }
            }
            const widgetFile = path_1.default.resolve(__dirname, "../templates/widget.jsx");
            const p1 = (0, promises_1.readFile)(widgetFile, { encoding: "utf-8" }).then((basicWidgetConfig) => {
                basicWidgetConfig = basicWidgetConfig
                    .replace(/__LABEL_PREFIX__/g, body.__LABEL_PREFIX__)
                    .replace(/__LISTING_NAME__/g, body.__LISTING_NAME__)
                    .replace(/__DISPLAY_DESCRIPTION__/g, body.__DISPLAY_DESCRIPTION__)
                    .replace(/__LISTING_ICON__/g, body.__LISTING_ICON__)
                    .replace(/__PLUGIN_REGISTRY_NAME__/g, body.__PLUGIN_REGISTRY_NAME__)
                    .replace(/__PLUGIN_NAME__/g, appId + "/" + body.__PLUGIN_NAME__);
                return (0, promises_1.writeFile)(path_1.default.resolve(pluginRoot, "source/widget.jsx"), basicWidgetConfig);
            });
            const componentFile = path_1.default.resolve(__dirname, "../templates/component.jsx");
            const p2 = (0, promises_1.readFile)(componentFile, { encoding: "utf-8" }).then((starterTemplate) => {
                starterTemplate = starterTemplate
                    .replace(/__LABEL_PREFIX__/g, body.__LABEL_PREFIX__)
                    .replace(/__LISTING_NAME__/g, body.__LISTING_NAME__)
                    .replace(/__DISPLAY_DESCRIPTION__/g, body.__DISPLAY_DESCRIPTION__)
                    .replace(/__LISTING_ICON__/g, body.__LISTING_ICON__)
                    .replace(/__PLUGIN_REGISTRY_NAME__/g, body.__PLUGIN_REGISTRY_NAME__)
                    .replace(/__PLUGIN_NAME__/g, appId + "/" + body.__PLUGIN_NAME__);
                return (0, promises_1.writeFile)(path_1.default.resolve(pluginRoot, "source/component.jsx"), starterTemplate);
            });
            const p3 = yield (0, promises_1.mkdir)(path_1.default.resolve(pluginRoot, "dist"), {
                recursive: true,
            });
            yield Promise.all([p1, p2, p3]);
            res.status(200);
            res.end();
        }
        catch (err) {
            console.error("in POST /create", err);
            next(err);
        }
    }
    else {
        console.log("Link doesn't exist. Ignoring");
        res.status(400);
        res.end();
    }
}));
router.get("/:appid/getall", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    // check if compiled files exist
    const appId = req.params.appid;
    try {
        const pluginBundleFilePath = yield (0, workspace_1.getPluginBundle)(appId);
        res.sendFile(pluginBundleFilePath);
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appId/compileall", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appId;
        const result = yield (0, workspace_1.compilePluginBundle)(appId);
        res.send(result);
    }
    catch (err) {
        console.error("in /compileall", err);
        if ((err === null || err === void 0 ? void 0 : err.message) && (err === null || err === void 0 ? void 0 : err.errors)) {
            res.json(err);
        }
        else {
            next(err);
        }
    }
}));
router.delete("/:appid/deleteallchats", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        console.log(`[DELETE] working one Deleting all chats for appId: ${appId}`);
        // Delete all chat messages and chats in a transaction
        if (isPostgresEnabled) {
            // First delete messages for chats with exact appId match
            // Delete messages for chats with path containing appId
            const chatsExact = yield chat_1.default.findAll({ where: { outputFile: appId } });
            const chatsPath = yield chat_1.default.findAll({ where: { outputFile: { [sequelize_1.Op.like]: `%${appId}%` } } });
            const chatIdsExact = chatsExact.map(chat => chat.id);
            const chatIdsPath = chatsPath.map(chat => chat.id);
            const deletedMessagesExact = yield chatmessage_1.default.destroy({ where: { chatId: {
                        [sequelize_1.Op.in]: chatIdsExact
                    } } });
            console.log(`[DELETE] Deleted ${deletedMessagesExact} chat messages with exact appId match`);
            const deletedMessagesPath = yield chatmessage_1.default.destroy({ where: { chatId: {
                        [sequelize_1.Op.in]: chatIdsPath
                    } } });
            console.log(`[DELETE] Deleted ${deletedMessagesPath} chat messages with path containing appId`);
            // Delete chats with exact appId match
            const deletedChatsExact = yield chat_1.default.destroy({ where: { outputFile: appId } });
            console.log(`[DELETE] Deleted ${deletedChatsExact} chats with exact appId match`);
            // Delete chats with path containing appId
            const deletedChatsPath = yield chat_1.default.destroy({ where: { outputFile: { [sequelize_1.Op.like]: `%${appId}%` } } });
            console.log(`[DELETE] Deleted ${deletedChatsPath} chats with path containing appId`);
        }
        else {
            cliconfig_1.default.transaction(() => {
                // First delete messages for chats with exact appId match
                const deleteMessagesExactStmt = cliconfig_1.default.prepare(`
          DELETE FROM chat_message
          WHERE chatId IN (
            SELECT id FROM chat
            WHERE outputFile = ?
          )
        `);
                const messagesExactResult = deleteMessagesExactStmt.run(appId);
                console.log(`[DELETE] Deleted ${messagesExactResult.changes} chat messages with exact appId match`);
                // Delete messages for chats with path containing appId
                const deleteMessagesPathStmt = cliconfig_1.default.prepare(`
          DELETE FROM chat_message
          WHERE chatId IN (
            SELECT id FROM chat
            WHERE outputFile LIKE ?
          )
        `);
                const messagesPathResult = deleteMessagesPathStmt.run(`%${appId}%`);
                console.log(`[DELETE] Deleted ${messagesPathResult.changes} chat messages with path containing appId`);
                // Delete chats with exact appId match
                const deleteChatsExactStmt = cliconfig_1.default.prepare(`
          DELETE FROM chat
          WHERE outputFile = ?
        `);
                const chatsExactResult = deleteChatsExactStmt.run(appId);
                console.log(`[DELETE] Deleted ${chatsExactResult.changes} chats with exact appId match`);
                // Delete chats with path containing appId
                const deleteChatsPathStmt = cliconfig_1.default.prepare(`
          DELETE FROM chat
          WHERE outputFile LIKE ?
        `);
                const chatsPathResult = deleteChatsPathStmt.run(`%${appId}%`);
                console.log(`[DELETE] Deleted ${chatsPathResult.changes} chats with path containing appId`);
            })();
        }
        console.log(`[DELETE] Successfully deleted all chats for appId: ${appId}`);
        res.status(200).json({ message: "All chats deleted successfully" });
    }
    catch (err) {
        console.error("Error deleting app chats:", err);
        next(err);
    }
}));
router.get("/:appid/:assetname/source", (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            let editableFilePath = "source/component.jsx";
            try {
                const metadataPath = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}/metadata.json`);
                const metadata = yield (0, promises_1.readFile)(metadataPath, { encoding: "utf8" });
                const parsedMeta = JSON.parse(metadata);
                editableFilePath = parsedMeta.editableFilePath;
            }
            catch (err) {
                console.error("Metadata file not found for plugin", pluginName);
            }
            const remoteCode = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}`, editableFilePath);
            console.log(`Looking for source file: ${remoteCode}`);
            res.sendFile(remoteCode);
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        (0, websocket_1.sendLog)("in GET /:name/source" + (err === null || err === void 0 ? void 0 : err.message));
        if ((err === null || err === void 0 ? void 0 : err.message) && (err === null || err === void 0 ? void 0 : err.errors)) {
            res.json(err);
        }
        else {
            console.error("Open the app first");
            res.status(500);
            res.send("in /:name/source a server error occured. Check server logs.");
        }
    }
    // return the component source code
}));
router.post("/:appid/:assetname/source", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        const code = req.body.code;
        if (openedApp) {
            let editableFilePath = "source/component.jsx";
            try {
                const metadataPath = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}/metadata.json`);
                const metadata = yield (0, promises_1.readFile)(metadataPath, { encoding: "utf8" });
                const parsedMeta = JSON.parse(metadata);
                editableFilePath = parsedMeta.editableFilePath;
            }
            catch (err) {
                console.error("Metadata file not found for plugin", pluginName);
            }
            const sourceFilePath = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}`, editableFilePath);
            const results = yield (0, promises_1.writeFile)(sourceFilePath, code);
            res.json(results);
        }
        else {
            (0, websocket_1.sendLog)(`Link not found, cannot write source for: ${pluginName}`);
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        console.error("in POST /:name/source", err);
        next(err);
    }
}));
router.get("/:appid/:assetname/bundle", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        if (!openedApp) {
            res.status(404).json({
                message: "App not found. Please open the app first."
            });
            return;
        }
        // Get the plugin folder path
        const pluginRoot = path_1.default.resolve(openedApp.repoPath, "remoteCode/plugins", pluginName);
        // Check if the plugin exists
        try {
            yield (0, promises_1.stat)(pluginRoot);
        }
        catch (err) {
            if ((err === null || err === void 0 ? void 0 : err.code) === "ENOENT") {
                res.status(404).json({
                    message: `Plugin '${pluginName}' not found.`
                });
                return;
            }
            throw err;
        }
        // Get the remoteCode path
        const remoteCode = path_1.default.resolve(openedApp.repoPath, "remoteCode");
        try {
            // Get the generated folder name
            const generatedRoot = path_1.default.resolve(remoteCode, "generated");
            const generatedFolderName = (0, js_sha256_1.sha256)(pluginName).toString();
            const bundlePath = path_1.default.resolve(generatedRoot, generatedFolderName, "dist/bundle.js");
            // Check if the bundle exists, if not compile it
            let bundleCode;
            try {
                yield (0, promises_1.stat)(bundlePath);
                bundleCode = yield (0, promises_1.readFile)(bundlePath, { encoding: "utf8" });
            }
            catch (err) {
                if ((err === null || err === void 0 ? void 0 : err.code) === "ENOENT") {
                    // Compile the plugin
                    try {
                        // Create the directory structure
                        yield (0, promises_1.mkdir)(path_1.default.resolve(generatedRoot, generatedFolderName, "dist"), { recursive: true });
                        // Compile the plugin
                        const compileResult = yield (0, compiler_1.compileMultiplePlugins)(remoteCode, [pluginName], generatedFolderName);
                        if (compileResult.errors && compileResult.errors.length > 0) {
                            res.status(400).json({
                                message: "Compilation failed",
                                errors: compileResult.errors
                            });
                            return;
                        }
                        // Read the compiled bundle
                        bundleCode = yield (0, promises_1.readFile)(bundlePath, { encoding: "utf8" });
                    }
                    catch (compileErr) {
                        console.error("Failed to compile plugin:", compileErr);
                        res.status(500).json({
                            message: "Failed to compile plugin",
                            errors: [{ error: (compileErr === null || compileErr === void 0 ? void 0 : compileErr.toString()) || "Unknown error", location: "compiler" }]
                        });
                        return;
                    }
                }
                else {
                    throw err;
                }
            }
            // Return the bundle code
            res.setHeader("Content-Type", "text/javascript");
            res.send(bundleCode);
        }
        catch (err) {
            console.error("Error processing plugin bundle:", err);
            res.status(500).json({
                message: "Failed to process plugin bundle",
                error: (err === null || err === void 0 ? void 0 : err.toString()) || "Unknown error"
            });
        }
    }
    catch (err) {
        console.error("in GET /:appid/:assetname/bundle", err);
        next(err);
    }
}));
router.delete("/:appid/:assetname", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            // 1. Delete plugin files
            const dirPath = path_1.default.resolve(openedApp.repoPath, "remoteCode/plugins", pluginName, "source", "component.jsx");
            // 2. Delete associated chat and messages
            const chatFilePath = dirPath; // This is what's stored in outputFile
            const deleteChatsQuery = cliconfig_1.default.prepare(`
        DELETE FROM chat_message WHERE chatId IN (
          SELECT id FROM chat
          WHERE outputFile = ? AND type = 'widget'
        )
      `);
            const deleteChatQuery = cliconfig_1.default.prepare(`
        DELETE FROM chat
        WHERE outputFile = ? AND type = 'widget'
      `);
            if (isPostgresEnabled) {
                const chats = yield chat_1.default.findAll({ where: { outputFile: chatFilePath, type: 'widget' } });
                const chatIds = chats.map((chat) => chat.id);
                const deletedMessages = yield chatmessage_1.default.destroy({ where: { chatId: chatIds } });
                const deletedChats = yield chat_1.default.destroy({ where: { outputFile: chatFilePath, type: 'widget' } });
                console.log(`[DELETE][Postgres] Deleted ${deletedMessages} chat messages and ${deletedChats} chats for filePath: ${chatFilePath}`);
            }
            else {
                // Run deletions in transaction
                cliconfig_1.default.transaction(() => {
                    deleteChatsQuery.run(chatFilePath);
                    deleteChatQuery.run(chatFilePath);
                })();
            }
            // Delete plugin directory
            yield (0, promises_1.rm)(path_1.default.dirname(path_1.default.dirname(dirPath)), { recursive: true, maxRetries: 4 });
            res.status(200).end();
        }
        else {
            res.status(404).end();
        }
    }
    catch (err) {
        console.error("in DELETE /:assetname", err);
        next(err);
    }
}));
router.post("/prompt/:appid/:assetname/provider/:provider/model/:model", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    let apptileUserEmail = JSON.stringify(req.header('x-apptile-user-email'));
    let apptileUserId = req.header('x-apptile-user-id');
    logger_1.logger.info("Got apptile user: " + apptileUserEmail);
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const model = req.params.model;
        if (!(0, baseAgent_2.narrowLLMProvider)(req.params.provider)) {
            console.error("Invalid provider found " + req.params.provider);
            res.status(400);
            res.send("Invalid llm provider: " + req.params.provider);
            return;
        }
        if (!req.body.temp_id) {
            res.status(400);
            res.send("Prompts must contain a temp_id");
            return;
        }
        res.setHeader("Content-Type", "text/plain");
        let result;
        let verifiedModel;
        if (req.params.provider === "openai" && (0, baseAgent_1.narrowOpenAIModel)(model)) {
            verifiedModel = model;
        }
        else if (req.params.provider === "google" && (0, baseAgent_1.narrowGoogleModel)(model)) {
            verifiedModel = model;
        }
        else if (req.params.provider === "amazon" && (0, baseAgent_1.narrowAmazonModel)(model)) {
            verifiedModel = model;
        }
        else if (req.params.provider === "claude" && (0, baseAgent_1.narrowAnthropicModel)(model)) {
            verifiedModel = model;
        }
        else {
            res.status(400);
            res.send("Could not figure out which LLM to use!");
            return;
        }
        try {
            if (req.body.usePlanner === true) {
                result = yield plannerAgent.runPrompt(appId, "", req.body.message, req, res, verifiedModel, req.params.provider, apptileUserEmail, req.body.temp_id);
            }
            else {
                result = yield pluginAgent.runPrompt(appId, pluginName, req.body.message, req, res, verifiedModel, req.params.provider, apptileUserEmail, req.body.temp_id);
            }
        }
        catch (err) {
            console.error("Plugin agent error!", err);
            res.status(500);
            res.end();
        }
        if (result && result.tokenCounterInstance && result.tokenCounterInstance.getTokenCount) {
            const tokenCounts = yield result.tokenCounterInstance.getTokenCount();
            if (!tokenCounts) {
                console.error(chalk_1.default.red('Failed to calculate tokens from response in plugin route'));
            }
            else {
                //Send the data to apptile server
                if (!apptileUserId) {
                    console.error("Failed to record token usage in plugin route. No apptile user id found");
                }
                else {
                    (0, apptileServerTokenManagement_1.recordTokenUsage)({
                        appId,
                        userId: apptileUserId,
                        inputTokens: tokenCounts.inputTokenCount,
                        outputTokens: tokenCounts.outputTokenCount,
                        llmModel: req.params.model
                    }, appId);
                }
                console.log(chalk_1.default.green("Plugin token counts: " + JSON.stringify(tokenCounts, null, 2)));
            }
        }
    }
    catch (err) {
        next(err);
    }
}));
router.get("/chathistory/v2/:appid/provider/:provider/model/:model", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    // Get chat history
    const appid = req.params.appid;
    const model = req.params.model;
    let provider;
    if (!(0, baseAgent_2.narrowLLMProvider)(req.params.provider)) {
        logger_1.logger.error("Invalid llm provider: " + req.params.provider);
        res.status(400);
        res.end();
        return;
    }
    else {
        provider = req.params.provider;
    }
    try {
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appid);
        if (!openedApp) {
            throw new Error("Chat cannot be found when app is not open");
        }
        else {
            let anchor = appid;
            const chat = yield (0, cliconfig_1.getChat)(anchor);
            res.setHeader("Content-Type", "text/plain");
            if (chat) {
                const messages = yield (0, cliconfig_1.getChatMessages)(chat.id, "DESC", 1000);
                const sequenced = (0, cliconfig_1.sequenceToolCallAndResponses)(messages, true);
                res.write(JSON.stringify({ chat, messages: sequenced }) + "plugin_response_json_separator");
            }
            else {
                const chat = yield (0, cliconfig_1.createChat)(anchor, "widget", provider, model, appid);
                res.write(JSON.stringify({ chat, messages: [] }) + "plugin_response_json_separator");
            }
            try {
                const plugins = yield listPluginNames(openedApp.repoPath);
                for (let pluginName of plugins) {
                    const pluginFilePath = path_1.default.resolve(openedApp.repoPath, "remoteCode", "plugins", pluginName, "source", "component.jsx");
                    // Get the chat for this plugin
                    const pluginChat = yield (0, cliconfig_1.getChat)(pluginFilePath);
                    if (pluginChat) {
                        // Get all messages for this plugin chat
                        const pluginMessages = yield (0, cliconfig_1.getChatMessages)(pluginChat.id, "DESC", 1000);
                        const sequencedPluginMessages = (0, cliconfig_1.sequenceToolCallAndResponses)(pluginMessages, true);
                        res.write(JSON.stringify({
                            chat: pluginChat,
                            pluginName,
                            messages: sequencedPluginMessages
                        }) + "plugin_response_json_separator");
                    }
                }
            }
            catch (err) {
                logger_1.logger.error("Failed when trying to get plugin names!" + err);
            }
            res.end();
        }
        // Get all the chats for the plugin agents 
        // Stream down the messages for for all the plugin chats
    }
    catch (err) {
        logger_1.logger.error("Error getting chat history:" + err);
        res.status(400).json({ error: err.message });
    }
}));
router.get("/chathistory/v2/messageImg/:messageId", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    // return the image for a message
}));
router.get("/chathistory/:appid/:assetname/provider/:provider/model/:model", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appid = req.params.appid;
    const assetname = req.params.assetname;
    const model = req.params.model;
    const limit = req.query.limit ? parseInt(req.query.limit) : 200;
    let provider;
    if (!(0, baseAgent_2.narrowLLMProvider)(req.params.provider)) {
        console.error("Invalid llm provider: ", req.params.provider);
        res.status(400);
        res.end();
        return;
    }
    else {
        provider = req.params.provider;
    }
    try {
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appid);
        if (!openedApp) {
            throw new Error("Chat cannot be found when app is not open");
        }
        else {
            let anchor = path_1.default.resolve(openedApp.repoPath, "remoteCode", "plugins", assetname, "source", "component.jsx");
            try {
                const entrystat = yield (0, promises_1.stat)(anchor);
                if (!entrystat.isFile()) {
                    anchor = assetname;
                }
            }
            catch (err) {
                anchor = assetname;
            }
            const chat = yield (0, cliconfig_1.getChat)(anchor);
            if (chat) {
                const messages = yield (0, cliconfig_1.getChatMessages)(chat.id, "DESC", limit);
                const sequenced = (0, cliconfig_1.sequenceToolCallAndResponses)(messages, true);
                // See if plugin name exists in tool_use messages and then find the corresponding chat for that plugin in chat table then get all the chat messages for that chat id and add it in the tool_use message
                const enhancedMessages = yield Promise.all(sequenced.map((message) => __awaiter(void 0, void 0, void 0, function* () {
                    if (message.content_type === 'tool_use' && message.tool_name) {
                        // Check if the tool_name contains a plugin reference
                        // Tool names like "nocodelayer_generate_code_for_plugin" might contain plugin info in the content
                        try {
                            const toolContent = JSON.parse(message.content);
                            let pluginName = null;
                            // Extract plugin name from tool content
                            if (toolContent.name) {
                                pluginName = toolContent.name;
                            }
                            else if (toolContent.plugin_name) {
                                pluginName = toolContent.plugin_name;
                            }
                            else if (toolContent.assetname) {
                                pluginName = toolContent.assetname;
                            }
                            if (pluginName) {
                                // Find the corresponding chat for this plugin
                                const pluginFilePath = path_1.default.resolve(openedApp.repoPath, "remoteCode", "plugins", pluginName, "source", "component.jsx");
                                // Get the chat for this plugin
                                const pluginChat = yield (0, cliconfig_1.getChat)(pluginFilePath);
                                if (pluginChat) {
                                    // Get all messages for this plugin chat
                                    const pluginMessages = yield (0, cliconfig_1.getChatMessages)(pluginChat.id, "DESC", limit);
                                    const sequencedPluginMessages = (0, cliconfig_1.sequenceToolCallAndResponses)(pluginMessages, true);
                                    // Add plugin chat messages to the tool_use message
                                    return Object.assign(Object.assign({}, message), { pluginAgentMessages: sequencedPluginMessages });
                                }
                            }
                        }
                        catch (err) {
                            console.error("Error parsing tool content for plugin extraction:", err);
                        }
                    }
                    return message;
                })));
                res.json({ chat, messages: enhancedMessages });
            }
            else {
                const chat = (0, cliconfig_1.createChat)(anchor, "widget", provider, model, appid);
                res.json({ chat, messages: [] });
            }
        }
    }
    catch (err) {
        console.error("Error getting chat history:", err);
        res.status(400).json({ error: err.message });
    }
}));
// router.post('/prompt-web/:appid/provider/:provider/model/:model', jsonParser, async (req, res, next) => {
//   try {
//     const model = req.params.model;
//     const appid = req.params.appid
//     const userPrompt = req.body.prompt || '';
//     const userCode = req.body.code || '';
//     const availableScreens = req.body.availableScreens || ''
//     // Sanity checks
//     if (!userPrompt) {
//       res.status(400).json({ code: '', message: 'Missing prompt message' });
//       return;
//     }
//     if (!narrowLLMProvider(req.params.provider)) {
//       console.error("Invalid provider found " + req.params.provider);
//       res.status(400);
//       res.json({ code: '', message: 'Invalid provider' });
//       return;
//     }
//     // Set proper content type for JSON response
//     res.setHeader('Content-Type', 'application/json');
//     // Call the updated prompt function with history and code
//     let result = ''
//     if (req.params.provider === "openai") {
//       result = await webPromptOpenAI(userPrompt, model, appid, userCode, availableScreens);
//     } else {
//       result = await webPromptClaude(userPrompt, model, appid, userCode, availableScreens);
//     }
//     // Send the response in the expected format
//     res.json({
//       code: result,
//     });
//   } catch (err) {
//     console.error("Error processing prompt:", err);
//     res.status(500).json({
//       code: '',
//       message: `Error occurred: ${err instanceof Error ? err.message : 'Unknown error'}`
//     });
//   }
// });
exports.default = router;
