/**
 * Query Controller
 *
 * API endpoints for federated query messages.
 */

import { Controller, Post, Get, Body, Param, Query, UseGuards, Req, Logger } from "@nestjs/common";
import { QueryService } from "./query.service";
import { AuthGuard } from "../auth/guards/auth.guard";
import { SendQueryDto, IncomingQueryDto } from "./dto/query.dto";
import type { AuthenticatedRequest } from "../common/types/user.types";
import type { QueryMessageDetails, QueryResponse } from "./types/message.types";
import type { FederationMessageStatus } from "@prisma/client";

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

  constructor(private readonly queryService: QueryService) {}

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

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

    return this.queryService.sendQuery(
      req.user.workspaceId,
      dto.connectionId,
      dto.query,
      dto.context
    );
  }

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

    return this.queryService.handleIncomingQuery(dto);
  }

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

    return this.queryService.getQueryMessages(req.user.workspaceId, status);
  }

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

    return this.queryService.getQueryMessage(req.user.workspaceId, messageId);
  }
}
