/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
import { Processor, WorkerHost } from "@nestjs/bullmq";
import { Logger } from "@nestjs/common";
import { Job } from "bullmq";
import {
  PREDICTIONS_QUEUE,
  PredictionJobType,
  PredictMatchJobData,
  SmartCouponJobData,
} from "./predictions.types";
import axios from "axios";

/**
 * Predictions Processor
 * Handles heavy AI computations in background via HTTP calls to AI Engine
 */
@Processor(PREDICTIONS_QUEUE)
export class PredictionsProcessor extends WorkerHost {
  private readonly logger = new Logger(PredictionsProcessor.name);
  private readonly aiEngineUrl: string;

  constructor() {
    super();
    // Default to container service URL
    this.aiEngineUrl = process.env.AI_ENGINE_URL || "http://ai-engine:8000";
  }

  async process(job: Job<any, any, string>): Promise<any> {
    this.logger.debug(`Processing job ${job.id}: ${job.name}`);

    switch (job.name) {
      case PredictionJobType.PREDICT_MATCH:
        return this.handlePredictMatch(job.data as PredictMatchJobData);

      case PredictionJobType.SMART_COUPON:
        return this.handleSmartCoupon(job.data as SmartCouponJobData);

      default:
        throw new Error(`Unknown job type: ${job.name}`);
    }
  }

  /**
   * Handle Single Match Prediction
   * HTTP POST /v20plus/analyze/:id
   */
  private async handlePredictMatch(data: PredictMatchJobData): Promise<any> {
    const { matchId } = data;
    this.logger.log(`🤖 AI Engine: Predicting match ${matchId}...`);

    try {
      const response = await axios.post(
        `${this.aiEngineUrl}/v20plus/analyze/${matchId}`,
        {
          simulate: data.simulate,
          is_simulation: data.is_simulation,
          pre_match_only: data.pre_match_only,
        },
        { timeout: 30000 },
      );
      return response.data;
    } catch (error) {
      throw this.mapAxiosError(error, matchId, "predict");
    }
  }

  /**
   * Handle Smart Coupon Generation
   * HTTP POST /v20plus/coupon
   */
  private async handleSmartCoupon(data: SmartCouponJobData): Promise<any> {
    const { matchIds, strategy } = data;
    this.logger.log(`🎫 AI Engine: Generating ${strategy} Coupon...`);

    try {
      const response = await axios.post(
        `${this.aiEngineUrl}/v20plus/coupon`,
        {
          match_ids: matchIds,
          strategy,
          max_matches: data.options?.maxMatches,
          min_confidence: data.options?.minConfidence,
        },
        { timeout: 60000 },
      );
      return response.data;
    } catch (error) {
      throw this.mapAxiosError(error, matchIds.join(","), "smart-coupon");
    }
  }

  private mapAxiosError(
    error: unknown,
    identifier: string,
    flow: "predict" | "smart-coupon",
  ): Error {
    if (!axios.isAxiosError(error)) {
      return error instanceof Error
        ? error
        : new Error(`AI_ENGINE_UNKNOWN|${flow}|Unknown error`);
    }

    const status = error.response?.status;
    const detail = error.response?.data?.detail || error.message;
    const code = error.code || "";

    if (status === 502) {
      this.logger.error(`AI Engine 502 (${flow}:${identifier}): ${detail}`);
      return new Error(`AI_ENGINE_502|${flow}|${detail}`);
    }

    if (status === 504) {
      this.logger.error(`AI Engine 504 (${flow}:${identifier}): ${detail}`);
      return new Error(`AI_ENGINE_504|${flow}|${detail}`);
    }

    if (code === "ECONNABORTED" || code === "ETIMEDOUT") {
      this.logger.error(`AI Engine timeout (${flow}:${identifier}): ${detail}`);
      return new Error(`AI_ENGINE_TIMEOUT|${flow}|${detail}`);
    }

    this.logger.error(
      `AI Engine error (${flow}:${identifier}) [${status ?? "N/A"}]: ${detail}`,
    );
    return new Error(`AI_ENGINE_ERROR|${flow}|${detail}`);
  }
}
