import { screen, Region } from '@nut-tree-fork/nut-js';
import type { ScreenRegion } from '../../../domain/value-objects/ScreenRegion';
import type { ScreenCaptureResult } from '../../../application/ports/IScreenAutomation';
import type { ILogger } from '../../../application/ports/ILogger';
import { NoOpLogAdapter } from '../logging/NoOpLogAdapter';

/**
 * Service for capturing screen regions using nut.js.
 * Provides screen capture functionality for template matching and visual automation.
 */
export class ScreenRecognitionService {
  private logger: ILogger;

  constructor(logger?: ILogger) {
    this.logger = logger ?? new NoOpLogAdapter();
  }

  /**
   * Capture the entire screen.
   * @returns ScreenCaptureResult with image buffer data
   */
  async captureFullScreen(): Promise<ScreenCaptureResult> {
    const startTime = Date.now();
    
    try {
      const width = await screen.width();
      const height = await screen.height();
      
      this.logger.debug('Capturing full screen', { width, height });
      
      const image = await screen.grab();
      const data = await image.toRGB();
      
      const durationMs = Date.now() - startTime;
      this.logger.debug('Screen capture completed', { durationMs, width, height });
      
      return {
        success: true,
        data: Buffer.from(data.data),
        width: data.width,
        height: data.height,
      };
    } catch (error) {
      const errorMsg = `Screen capture failed: ${error}`;
      this.logger.error('Screen capture failed', error instanceof Error ? error : new Error(errorMsg));
      
      return {
        success: false,
        error: errorMsg,
      };
    }
  }

  /**
   * Capture a specific region of the screen.
   * @param region - The rectangular region to capture
   * @returns ScreenCaptureResult with image buffer data
   */
  async captureRegion(region: ScreenRegion): Promise<ScreenCaptureResult> {
    const startTime = Date.now();
    
    try {
      this.logger.debug('Capturing screen region', { region });
      
      const nutRegion = new Region(region.x, region.y, region.width, region.height);
      const image = await screen.grabRegion(nutRegion);
      const data = await image.toRGB();
      
      const durationMs = Date.now() - startTime;
      this.logger.debug('Region capture completed', { durationMs, region });
      
      return {
        success: true,
        data: Buffer.from(data.data),
        width: data.width,
        height: data.height,
      };
    } catch (error) {
      const errorMsg = `Region capture failed: ${error}`;
      this.logger.error('Region capture failed', error instanceof Error ? error : new Error(errorMsg), { region });
      
      return {
        success: false,
        error: errorMsg,
      };
    }
  }

  /**
   * Get the current screen dimensions.
   * @returns Object with width and height, or null on error
   */
  async getScreenDimensions(): Promise<{ width: number; height: number } | null> {
    try {
      const width = await screen.width();
      const height = await screen.height();
      return { width, height };
    } catch (error) {
      this.logger.error('Failed to get screen dimensions', error instanceof Error ? error : new Error(String(error)));
      return null;
    }
  }

  /**
   * Convert ScreenRegion to nut.js Region.
   * Utility method for internal use.
   */
  toNutRegion(region: ScreenRegion): Region {
    return new Region(region.x, region.y, region.width, region.height);
  }

  /**
   * Convert nut.js Region to ScreenRegion.
   * Utility method for internal use.
   */
  fromNutRegion(nutRegion: Region): ScreenRegion {
    return {
      x: nutRegion.left,
      y: nutRegion.top,
      width: nutRegion.width,
      height: nutRegion.height,
    };
  }
}