/**
 * Command Controller
 *
 * API endpoints for federated command messages.
 */

import { Controller, Post, Get, Body, Param, Query, UseGuards, Req, Logger } from "@nestjs/common";
import { CommandService } from "./command.service";
import { AuthGuard } from "../auth/guards/auth.guard";
import { SendCommandDto, IncomingCommandDto } from "./dto/command.dto";
import type { AuthenticatedRequest } from "../common/types/user.types";
import type { CommandMessageDetails, CommandResponse } from "./types/message.types";
import type { FederationMessageStatus } from "@prisma/client";

@Controller("v1/federation")
export class CommandController {
  private readonly logger = new Logger(CommandController.name);

  constructor(private readonly commandService: CommandService) {}

  /**
   * Send a command to a remote instance
   * Requires authentication
   */
  @Post("command")
  @UseGuards(AuthGuard)
  async sendCommand(
    @Req() req: AuthenticatedRequest,
    @Body() dto: SendCommandDto
  ): Promise<CommandMessageDetails> {
    if (!req.user?.workspaceId) {
      throw new Error("Workspace ID not found in request");
    }

    this.logger.log(
      `User ${req.user.id} sending command to connection ${dto.connectionId} in workspace ${req.user.workspaceId}`
    );

    return this.commandService.sendCommand(
      req.user.workspaceId,
      dto.connectionId,
      dto.commandType,
      dto.payload
    );
  }

  /**
   * Handle incoming command from remote instance
   * Public endpoint - no authentication required (signature-based verification)
   */
  @Post("incoming/command")
  async handleIncomingCommand(@Body() dto: IncomingCommandDto): Promise<CommandResponse> {
    this.logger.log(`Received command from ${dto.instanceId}: ${dto.messageId}`);

    return this.commandService.handleIncomingCommand(dto);
  }

  /**
   * Get all command messages for the workspace
   * Requires authentication
   */
  @Get("commands")
  @UseGuards(AuthGuard)
  async getCommands(
    @Req() req: AuthenticatedRequest,
    @Query("status") status?: FederationMessageStatus
  ): Promise<CommandMessageDetails[]> {
    if (!req.user?.workspaceId) {
      throw new Error("Workspace ID not found in request");
    }

    return this.commandService.getCommandMessages(req.user.workspaceId, status);
  }

  /**
   * Get a single command message
   * Requires authentication
   */
  @Get("commands/:id")
  @UseGuards(AuthGuard)
  async getCommand(
    @Req() req: AuthenticatedRequest,
    @Param("id") messageId: string
  ): Promise<CommandMessageDetails> {
    if (!req.user?.workspaceId) {
      throw new Error("Workspace ID not found in request");
    }

    return this.commandService.getCommandMessage(req.user.workspaceId, messageId);
  }
}
