import { Injectable } from '@nestjs/common';
import { LoggerService } from '@modules/shared';

export interface AiPredictRequest {
  area: number;
  district: string;
  city: string;
  property_type: string;
  bedrooms?: number;
  bathrooms?: number;
  floors?: number;
  frontage?: number;
  road_width?: number;
  year_built?: number | null;
  has_legal_paper?: boolean;
}

export interface AiPredictResponse {
  estimated_price_vnd: number;
  confidence: number;
  price_per_m2: number;
  price_range_low: number;
  price_range_high: number;
}

export interface AiModerationRequest {
  text: string;
  context?: string;
}

export interface AiModerationFlag {
  category: string;
  severity: string;
  matched_text: string;
  reason: string;
}

export interface AiModerationResponse {
  is_flagged: boolean;
  score: number;
  flags: AiModerationFlag[];
  cleaned_text: string | null;
}

export const AI_SERVICE_CLIENT = Symbol('AI_SERVICE_CLIENT');

export interface IAiServiceClient {
  predict(req: AiPredictRequest): Promise<AiPredictResponse>;
  moderate(req: AiModerationRequest): Promise<AiModerationResponse>;
  isAvailable(): Promise<boolean>;
}

@Injectable()
export class AiServiceClient implements IAiServiceClient {
  private readonly baseUrl: string;
  private readonly apiKey: string;
  private readonly timeoutMs: number;

  constructor(private readonly logger: LoggerService) {
    this.baseUrl = process.env['AI_SERVICE_URL'] ?? 'http://localhost:8000';
    this.apiKey = process.env['AI_SERVICE_API_KEY'] ?? '';
    this.timeoutMs = Number(process.env['AI_SERVICE_TIMEOUT_MS']) || 5000;
  }

  async predict(req: AiPredictRequest): Promise<AiPredictResponse> {
    return this.post<AiPredictResponse>('/avm/predict', req);
  }

  async moderate(req: AiModerationRequest): Promise<AiModerationResponse> {
    return this.post<AiModerationResponse>('/moderation/check', req);
  }

  async isAvailable(): Promise<boolean> {
    try {
      const response = await fetch(`${this.baseUrl}/health`, {
        method: 'GET',
        signal: AbortSignal.timeout(2000),
      });
      return response.ok;
    } catch {
      return false;
    }
  }

  private async post<T>(path: string, body: unknown): Promise<T> {
    const url = `${this.baseUrl}${path}`;
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
    };
    if (this.apiKey) {
      headers['X-API-Key'] = this.apiKey;
    }

    const response = await fetch(url, {
      method: 'POST',
      headers,
      body: JSON.stringify(body),
      signal: AbortSignal.timeout(this.timeoutMs),
    });

    if (!response.ok) {
      const text = await response.text().catch(() => '');
      throw new Error(`AI service ${path} returned ${response.status}: ${text}`);
    }

    return response.json() as Promise<T>;
  }
}
