import express, { Request } from "express";
import path from "path";
import { readdir, rm, mkdir, cp, readFile, writeFile, stat } from "node:fs/promises";
import bodyParser from "body-parser";
import { sendLog } from "../websocket";
import { compilePluginBundle, getPluginBundle } from "../controllers/workspace";
import db, {
  getOpenApp,
  getChatMessages,
  getChat,
  createChat,
  sequenceToolCallAndResponses,
  AgentProgramType,
} from "../database/cliconfig";
// import { prompt as promptOpenAI } from "../controllers/openaiAgent";
// import { promptWithoutChatSave as promptClaudeByPlanner } from "../controllers/claudeAgent";
// import { prompt as promptClaude } from "../controllers/claudeAgent";
import { PluginAgent } from "../controllers/agents/pluginAgent";
// import { AppPlannerAgent } from "../controllers/agents/appPlannerAgent";
// import { prompt as webPromptOpenAI } from '../controllers/webReactOpenAiAgent';
// import { prompt as webPromptClaude } from '../controllers/webReactClaudeAgent';
import { AmazonModels, AnthropicModels, GoogleModels, LLMProviders, narrowAmazonModel, narrowAnthropicModel, narrowGoogleModel, narrowOpenAIModel, OpenAIModels } from "../controllers/agents/baseAgent";
import { compileMultiplePlugins } from "../controllers/compiler";
import { sha256 } from "js-sha256";
import { logger } from "../utils/logger";
import chalk from "chalk";
import { recordTokenUsage } from "../services/apptileServerTokenManagement";
import { narrowLLMProvider } from "../controllers/agents/baseAgent";
import Chat, { IChatAttributes } from "../models/chat";
import ChatMessage from "../models/chatmessage";
import { Op } from "sequelize";
import { AppPlannerAgent } from "../controllers/agents/appPlannerAgent";


export const jsonParser = bodyParser.json({ limit: "50mb" });

const router = express.Router();

const pluginAgent = new PluginAgent();
const plannerAgent = new AppPlannerAgent();

const isPostgresEnabled = process.env.ENABLE_POSTGRES == 'true';

async function listPluginNames(repoPath: string) {
  const pluginsRoot = path.resolve(
    repoPath,
    "remoteCode/plugins"
  );

  try {
    const contents = await readdir(pluginsRoot, { withFileTypes: true });
    const dirs = contents
      .filter((it) => it.isDirectory())
      .map((it) => it.name);
    return dirs;
  } catch (err: any) {
    if (err?.code === "ENOENT") {
    } else {
      console.error("Unhandelable error", err);
      throw err;
    }
    return [];
  }
}

router.get("/:appid/list", async (req, res, next) => {
  try {
    const appId = req.params.appid;
    const openedApp = await getOpenApp(appId);
    if (openedApp) {
      try {
        const pluginNames = await listPluginNames(openedApp.repoPath);
        res.json(pluginNames);
      } catch (err) {
        next(err);
      }
    } else {
      res.status(404);
      res.end();
    }
  } catch (err) {
    next(err);
  }
});

router.post("/:appid/create", jsonParser, async (req, res, next) => {
  const appId = req.params.appid;
  const openedApp = await 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.resolve(
        openedApp.repoPath,
        `remoteCode/plugins`,
        name
      );
      try {
        await mkdir(path.resolve(pluginRoot, "source"), { recursive: true });
      } catch (err: any) {
        if (err?.code !== "EEXIST") {
          console.error("Unhandelable error", err);
          next(err);
        }
      }
      const widgetFile = path.resolve(__dirname, "../templates/widget.jsx");
      const p1 = 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 writeFile(
            path.resolve(pluginRoot, "source/widget.jsx"),
            basicWidgetConfig
          );
        }
      );
      const componentFile = path.resolve(
        __dirname,
        "../templates/component.jsx"
      );
      const p2 = 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 writeFile(
            path.resolve(pluginRoot, "source/component.jsx"),
            starterTemplate
          );
        }
      );

      const p3 = await mkdir(path.resolve(pluginRoot, "dist"), {
        recursive: true,
      });
      await 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",
  async (
    req: Request<{ appid: string }, {}, {}, { plugins: string }>,
    res,
    next
  ) => {
    // check if compiled files exist
    const appId = req.params.appid;
    try {
      const pluginBundleFilePath = await getPluginBundle(appId);
      res.sendFile(pluginBundleFilePath);
    } catch (err) {
      next(err);
    }
  }
);

router.post("/:appId/compileall", jsonParser, async (req, res, next) => {
  try {
    const appId = req.params.appId;
    const result = await compilePluginBundle(appId);
    res.send(result);
  } catch (err) {
    console.error("in /compileall", err);
    if ((err as any)?.message && (err as any)?.errors) {
      res.json(err as any);
    } else {
      next(err);
    }
  }
});

router.delete("/:appid/deleteallchats", async (req, res, next) => {
  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 = await Chat.findAll({ where: { outputFile: appId } });
      const chatsPath = await Chat.findAll({ where: { outputFile: { [Op.like]: `%${appId}%` } } });
      const chatIdsExact = chatsExact.map(chat => chat.id);
      const chatIdsPath = chatsPath.map(chat => chat.id);

      
      const deletedMessagesExact = await ChatMessage.destroy({ where: { chatId:{
        [Op.in]: chatIdsExact
      } } });
      console.log(`[DELETE] Deleted ${deletedMessagesExact} chat messages with exact appId match`);
      const deletedMessagesPath = await ChatMessage.destroy({ where: { chatId: {
        [Op.in]: chatIdsPath
      } } });
      console.log(`[DELETE] Deleted ${deletedMessagesPath} chat messages with path containing appId`);

      // Delete chats with exact appId match
      const deletedChatsExact = await Chat.destroy({ where: { outputFile: appId } });
      console.log(`[DELETE] Deleted ${deletedChatsExact} chats with exact appId match`);
      
      // Delete chats with path containing appId
      const deletedChatsPath = await Chat.destroy({ where: { outputFile: { [Op.like]: `%${appId}%` } } });
      console.log(`[DELETE] Deleted ${deletedChatsPath} chats with path containing appId`);
    } else {
      db.transaction(() => {
        // First delete messages for chats with exact appId match
        const deleteMessagesExactStmt = db.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 = db.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 = db.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 = db.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", async (req, res) => {
  try {
    const appId = req.params.appid;
    const pluginName = req.params.assetname;
    const openedApp = await getOpenApp(appId);
    if (openedApp) {
      let editableFilePath = "source/component.jsx";
      try {
        const metadataPath = path.resolve(
          openedApp.repoPath,
          `remoteCode/plugins/${pluginName}/metadata.json`
        );
        const metadata = await 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.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: any) {
    sendLog("in GET /:name/source" + err?.message);
    if ((err as any)?.message && (err as any)?.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", jsonParser, async (req, res, next) => {
  try {
    const appId = req.params.appid;
    const pluginName = req.params.assetname;
    const openedApp = await getOpenApp(appId);
    const code = req.body.code;

    if (openedApp) {
      let editableFilePath = "source/component.jsx";
      try {
        const metadataPath = path.resolve(
          openedApp.repoPath,
          `remoteCode/plugins/${pluginName}/metadata.json`
        );
        const metadata = await 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.resolve(
        openedApp.repoPath,
        `remoteCode/plugins/${pluginName}`,
        editableFilePath
      );
      const results = await writeFile(sourceFilePath, code);
      res.json(results);
    } else {
      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", async (req, res, next) => {
  try {
    const appId = req.params.appid;
    const pluginName = req.params.assetname;
    const openedApp = await 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.resolve(
      openedApp.repoPath,
      "remoteCode/plugins",
      pluginName
    );

    // Check if the plugin exists
    try {
      await stat(pluginRoot);
    } catch (err: any) {
      if (err?.code === "ENOENT") {
        res.status(404).json({
          message: `Plugin '${pluginName}' not found.`
        });
        return;
      }
      throw err;
    }

    // Get the remoteCode path
    const remoteCode = path.resolve(openedApp.repoPath, "remoteCode");

    try {
      // Get the generated folder name
      const generatedRoot = path.resolve(remoteCode, "generated");
      const generatedFolderName = sha256(pluginName).toString();
      const bundlePath = path.resolve(generatedRoot, generatedFolderName, "dist/bundle.js");

      // Check if the bundle exists, if not compile it
      let bundleCode;
      try {
        await stat(bundlePath);
        bundleCode = await readFile(bundlePath, { encoding: "utf8" });
      } catch (err: any) {
        if (err?.code === "ENOENT") {
          // Compile the plugin
          try {
            // Create the directory structure
            await mkdir(path.resolve(generatedRoot, generatedFolderName, "dist"), { recursive: true });

            // Compile the plugin
            const compileResult = await 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 = await readFile(bundlePath, { encoding: "utf8" });
          } catch (compileErr: any) {
            console.error("Failed to compile plugin:", compileErr);
            res.status(500).json({
              message: "Failed to compile plugin",
              errors: [{ error: 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: any) {
      console.error("Error processing plugin bundle:", err);
      res.status(500).json({
        message: "Failed to process plugin bundle",
        error: err?.toString() || "Unknown error"
      });
    }
  } catch (err) {
    console.error("in GET /:appid/:assetname/bundle", err);
    next(err);
  }
});

router.delete("/:appid/:assetname", async (req, res, next) => {
  try {
    const appId = req.params.appid;
    const pluginName = req.params.assetname;
    const openedApp = await getOpenApp(appId);
    if (openedApp) {
      // 1. Delete plugin files
      const dirPath = path.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 = db.prepare(`
        DELETE FROM chat_message WHERE chatId IN (
          SELECT id FROM chat
          WHERE outputFile = ? AND type = 'widget'
        )
      `);
      const deleteChatQuery = db.prepare(`
        DELETE FROM chat
        WHERE outputFile = ? AND type = 'widget'
      `);

      if (isPostgresEnabled) {
        const chats = await Chat.findAll({ where: { outputFile: chatFilePath, type: 'widget' } });
        const chatIds = chats.map((chat: IChatAttributes) => chat.id);
        const deletedMessages = await ChatMessage.destroy({ where: { chatId: chatIds } });
        const deletedChats = await Chat.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
        db.transaction(() => {
          deleteChatsQuery.run(chatFilePath);
          deleteChatQuery.run(chatFilePath);
        })();
      }

      // Delete plugin directory
      await rm(path.dirname(path.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",
  jsonParser,
  async (req, res, next) => { 
    let apptileUserEmail = JSON.stringify(req.header('x-apptile-user-email'));
    let apptileUserId = req.header('x-apptile-user-id');
    logger.info("Got apptile user: " + apptileUserEmail);
    try {
      const appId = req.params.appid;
      const pluginName = req.params.assetname;
      const model = req.params.model;
      if (!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: AnthropicModels|OpenAIModels|GoogleModels|AmazonModels;
      if (req.params.provider === "openai" && narrowOpenAIModel(model)) {
        verifiedModel = model;
      } else if (req.params.provider === "google" && narrowGoogleModel(model)) {
        verifiedModel = model;
      } else if (req.params.provider === "amazon" && narrowAmazonModel(model)) {
        verifiedModel = model;
      } else if (req.params.provider === "claude" && 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 = await plannerAgent.runPrompt(
            appId,
            "",
            req.body.message,
            req,
            res,
            verifiedModel,
            req.params.provider,
            apptileUserEmail,
            req.body.temp_id
          );
        } else {
          result = await 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 = await result.tokenCounterInstance.getTokenCount();
        if (!tokenCounts) {
          console.error(chalk.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 {
            recordTokenUsage(
              {
                appId,
                userId: apptileUserId,
                inputTokens: tokenCounts.inputTokenCount,
                outputTokens: tokenCounts.outputTokenCount,
                llmModel: req.params.model
              },
              appId
            );
          }
          console.log(
            chalk.green(
              "Plugin token counts: " + JSON.stringify(tokenCounts, null, 2)
            )
          );
        }
      }
    } catch (err) {
      next(err);
    }
  }
);

router.get(
  "/chathistory/v2/:appid/provider/:provider/model/:model",
  async (req, res, next) => {
    // Get chat history
    const appid = req.params.appid;
    const model = req.params.model;
    let provider: LLMProviders;
    if (!narrowLLMProvider(req.params.provider)) {
      logger.error("Invalid llm provider: " + req.params.provider);
      res.status(400);
      res.end();
      return;
    } else {
      provider = req.params.provider;
    }
 
    try {
      const openedApp = await getOpenApp(appid);
      if (!openedApp) {
        throw new Error("Chat cannot be found when app is not open");
      } else {
        let anchor = appid;
        const chat = await getChat(anchor);
        res.setHeader("Content-Type", "text/plain");
        if (chat) {
          const messages = await getChatMessages(chat.id, "DESC", 1000);
          const sequenced = sequenceToolCallAndResponses(messages, true);

          res.write(JSON.stringify({ chat, messages: sequenced }) + "plugin_response_json_separator");
        } else {
          const chat = await createChat(anchor, "widget", provider, model, appid);
          res.write(JSON.stringify({ chat, messages: [] }) + "plugin_response_json_separator");
        }

        try {
          const plugins = await listPluginNames(openedApp.repoPath);
          for (let pluginName of plugins) {
            const pluginFilePath = path.resolve(
              openedApp.repoPath,
              "remoteCode",
              "plugins",
              pluginName,
              "source",
              "component.jsx"
            );
            
            // Get the chat for this plugin
            const pluginChat = await getChat(pluginFilePath);
            
            if (pluginChat) {
              // Get all messages for this plugin chat

              const pluginMessages = await getChatMessages(pluginChat.id, "DESC", 1000);

              const sequencedPluginMessages = sequenceToolCallAndResponses(pluginMessages, true);         
              res.write(JSON.stringify({
                chat: pluginChat,
                pluginName,
                messages: sequencedPluginMessages
              }) + "plugin_response_json_separator");
            }
          }
        } catch (err) {
          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: any) {
      logger.error("Error getting chat history:" + err);
      res.status(400).json({ error: err.message });
    }
  }
);

router.get(
  "/chathistory/v2/messageImg/:messageId",
  async (req, res, next) => {
    // return the image for a message
  }
)

router.get(
  "/chathistory/:appid/:assetname/provider/:provider/model/:model",
  async (req, res, next) => {
    const appid = req.params.appid;
    const assetname = req.params.assetname;
    const model = req.params.model; 
    const limit = req.query.limit ? parseInt(req.query.limit as string) : 200;
    
    let provider: LLMProviders;
    if (!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 = await getOpenApp(appid);
      if (!openedApp) {
        throw new Error("Chat cannot be found when app is not open");
      } else {
        let anchor = path.resolve(
          openedApp.repoPath,
          "remoteCode",
          "plugins",
          assetname,
          "source",
          "component.jsx"
        );
        try {
          const entrystat = await stat(anchor);
          if (!entrystat.isFile()) {
            anchor = assetname;
          }
        } catch (err) {
          anchor = assetname;
        }
        const chat = await getChat(anchor);
        if (chat) {

          const messages = await getChatMessages(chat.id, "DESC", limit);

          const sequenced = 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 = await Promise.all(sequenced.map(async (message) => {
            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.resolve(
                    openedApp.repoPath,
                    "remoteCode",
                    "plugins",
                    pluginName,
                    "source",
                    "component.jsx"
                  );
                  
                  // Get the chat for this plugin
                  const pluginChat = await getChat(pluginFilePath);
                  
                  if (pluginChat) {
                    // Get all messages for this plugin chat

                    const pluginMessages = await getChatMessages(pluginChat.id, "DESC", limit);

                    const sequencedPluginMessages = sequenceToolCallAndResponses(pluginMessages, true);
                    
                    // Add plugin chat messages to the tool_use message
                    return {
                      ...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 = createChat(anchor, "widget", provider, model, appid);
          res.json({ chat, messages: [] });
        }
      }
    } catch (err: any) {
      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'}`
//     });
//   }
// });


export default router;
