import { Controller, Get, Query, UseGuards, BadRequestException } from "@nestjs/common";
import { AuthGuard } from "../auth/guards/auth.guard";
import { PredictionService } from "./prediction.service";
import {
  TaskType,
  Complexity,
  Provider,
  type PredictionResponse,
} from "@mosaicstack/telemetry-client";

/**
 * Valid values for query parameter validation.
 */
const VALID_TASK_TYPES = new Set<string>(Object.values(TaskType));
const VALID_COMPLEXITIES = new Set<string>(Object.values(Complexity));
const VALID_PROVIDERS = new Set<string>(Object.values(Provider));

/**
 * Response DTO for the estimate endpoint.
 */
interface EstimateResponseDto {
  data: PredictionResponse | null;
}

/**
 * Mosaic Telemetry Controller
 *
 * Provides API endpoints for accessing telemetry prediction data.
 * All endpoints require authentication via AuthGuard.
 *
 * This controller is intentionally lightweight - it delegates to PredictionService
 * for the actual prediction logic and returns results directly to the frontend.
 */
@Controller("telemetry")
@UseGuards(AuthGuard)
export class MosaicTelemetryController {
  constructor(private readonly predictionService: PredictionService) {}

  /**
   * GET /api/telemetry/estimate
   *
   * Get a cost/token estimate for a given task configuration.
   * Returns prediction data including confidence level, or null if
   * no prediction is available.
   *
   * @param taskType - Task type enum value (e.g. "implementation", "planning")
   * @param model - Model name (e.g. "claude-sonnet-4-5")
   * @param provider - Provider enum value (e.g. "anthropic", "openai")
   * @param complexity - Complexity level (e.g. "low", "medium", "high")
   * @returns Prediction response with estimates and confidence
   */
  @Get("estimate")
  getEstimate(
    @Query("taskType") taskType: string,
    @Query("model") model: string,
    @Query("provider") provider: string,
    @Query("complexity") complexity: string
  ): EstimateResponseDto {
    if (!taskType || !model || !provider || !complexity) {
      throw new BadRequestException(
        "Missing query parameters. Required: taskType, model, provider, complexity"
      );
    }

    if (!VALID_TASK_TYPES.has(taskType)) {
      throw new BadRequestException(
        `Invalid taskType "${taskType}". Valid values: ${[...VALID_TASK_TYPES].join(", ")}`
      );
    }

    if (!VALID_PROVIDERS.has(provider)) {
      throw new BadRequestException(
        `Invalid provider "${provider}". Valid values: ${[...VALID_PROVIDERS].join(", ")}`
      );
    }

    if (!VALID_COMPLEXITIES.has(complexity)) {
      throw new BadRequestException(
        `Invalid complexity "${complexity}". Valid values: ${[...VALID_COMPLEXITIES].join(", ")}`
      );
    }

    const prediction = this.predictionService.getEstimate(
      taskType as TaskType,
      model,
      provider as Provider,
      complexity as Complexity
    );

    return { data: prediction };
  }
}
