/**
 * @file Face Detector
 * @description Face detection module with canvas pooling
 * @module modules/face/detector
 */

import { FaceDetectionOptions, FaceDetectionResult } from './types';
import { CanvasPool } from '../../../core/utils/canvas-pool';
import { ImageSource } from '../../../core/config';

export class FaceDetector {
  private _options: Required<FaceDetectionOptions>;
  private _pool: CanvasPool;
  private _initialized: boolean = false;
  private _modelLoaded: boolean = false;

  constructor(options: FaceDetectionOptions = {}) {
    this._options = {
      maxFaces: options.maxFaces ?? 10,
      minFaceSize: options.minFaceSize ?? 0.1,
      confidenceThreshold: options.confidenceThreshold ?? 0.5,
      landmarks: options.landmarks ?? true,
      inputWidth: options.inputWidth ?? 640,
      inputHeight: options.inputHeight ?? 480,
    };
    this._pool = new CanvasPool();
  }

  get initialized(): boolean {
    return this._initialized;
  }

  async initialize(): Promise<void> {
    // Load model (lazy loading on demand)
    this._modelLoaded = true;
    this._initialized = true;
  }

  async detect(input: ImageSource): Promise<FaceDetectionResult[]> {
    if (!this._initialized) {
      throw new Error('FaceDetector not initialized');
    }

    // 1. Acquire canvas from pool
    const pooled = this._pool.acquire(this._options.inputWidth, this._options.inputHeight);

    try {
      // 2. Draw input to canvas
      const ctx = pooled.canvas.getContext('2d');
      if (!ctx) {
        throw new Error('Failed to get 2d context');
      }

      // Handle different input types
      if (input instanceof HTMLCanvasElement) {
        ctx.drawImage(input, 0, 0);
      } else if (input instanceof HTMLImageElement || input instanceof HTMLVideoElement) {
        ctx.drawImage(input, 0, 0, this._options.inputWidth, this._options.inputHeight);
      } else if (input instanceof ImageData) {
        ctx.putImageData(input, 0, 0);
      }
      // string input (URL) would need async loading — not implemented in stub

      // 3. Run detection (stub returns empty)
      // TODO: Integrate real model

      // 4. Convert results and return
      const results: FaceDetectionResult[] = [];
      // stub: no faces detected

      return results;
    } finally {
      // 5. Release canvas back to pool
      this._pool.release(pooled);
    }
  }

  async destroy(): Promise<void> {
    this._pool.clear();
    this._initialized = false;
    this._modelLoaded = false;
  }
}