import type { AuthenticatedRequest } from "../../../types/index.js";
import type { Request, RequestHandler, Response, Router } from "express";
import { sshLogger } from "../../utils/logger.js";
import { createCurrentCommandHistoryRepository } from "../repositories/factory.js";
import { isNonEmptyString } from "./host-normalizers.js";

export function registerHostCommandHistoryRoutes(
  router: Router,
  authenticateJWT: RequestHandler,
): void {
  /**
   * @openapi
   * /host/command-history/{hostId}:
   *   get:
   *     summary: Get command history
   *     description: Retrieves the command history for a specific host.
   *     tags:
   *       - SSH
   *     parameters:
   *       - in: path
   *         name: hostId
   *         required: true
   *         schema:
   *           type: integer
   *     responses:
   *       200:
   *         description: A list of commands.
   *       400:
   *         description: Invalid userId or hostId.
   *       500:
   *         description: Failed to fetch command history.
   */
  router.get(
    "/command-history/:hostId",
    authenticateJWT,
    async (req: Request, res: Response) => {
      const userId = (req as AuthenticatedRequest).userId;
      const hostIdParam = Array.isArray(req.params.hostId)
        ? req.params.hostId[0]
        : req.params.hostId;
      const hostId = parseInt(hostIdParam, 10);

      if (!isNonEmptyString(userId) || !hostId) {
        sshLogger.warn("Invalid userId or hostId for command history fetch", {
          operation: "command_history_fetch",
          hostId,
          userId,
        });
        return res.status(400).json({ error: "Invalid userId or hostId" });
      }

      try {
        const history =
          await createCurrentCommandHistoryRepository().listCommandsForHost(
            userId,
            hostId,
          );

        res.json(history);
      } catch (err) {
        sshLogger.error("Failed to fetch command history from database", err, {
          operation: "command_history_fetch",
          hostId,
          userId,
        });
        res.status(500).json({ error: "Failed to fetch command history" });
      }
    },
  );

  /**
   * @openapi
   * /host/command-history:
   *   delete:
   *     summary: Delete command from history
   *     description: Deletes a specific command from the history of a host.
   *     tags:
   *       - SSH
   *     requestBody:
   *       required: true
   *       content:
   *         application/json:
   *           schema:
   *             type: object
   *             properties:
   *               hostId:
   *                 type: integer
   *               command:
   *                 type: string
   *     responses:
   *       200:
   *         description: Command deleted from history.
   *       400:
   *         description: Invalid data.
   *       500:
   *         description: Failed to delete command.
   */
  router.delete(
    "/command-history",
    authenticateJWT,
    async (req: Request, res: Response) => {
      const userId = (req as AuthenticatedRequest).userId;
      const { hostId, command } = req.body;

      if (!isNonEmptyString(userId) || !hostId || !command) {
        sshLogger.warn("Invalid data for command history deletion", {
          operation: "command_history_delete",
          hostId,
          userId,
        });
        return res.status(400).json({ error: "Invalid data" });
      }

      try {
        await createCurrentCommandHistoryRepository().deleteCommandForHost(
          userId,
          hostId,
          command,
        );

        res.json({ message: "Command deleted from history" });
      } catch (err) {
        sshLogger.error("Failed to delete command from history", err, {
          operation: "command_history_delete",
          hostId,
          userId,
          command,
        });
        res.status(500).json({ error: "Failed to delete command" });
      }
    },
  );
}
