/**
 * Screenshot command - Cross-platform screenshot capture
 *
 * Captures screenshots using native OS tools:
 * - Windows: PowerShell + System.Drawing + Win32 API
 * - macOS: screencapture + osascript
 * - Linux: maim/scrot + xdotool
 *
 * No project index required - standalone utility.
 *
 * v1.9.0 - Initial implementation
 */

import { tmpdir } from 'os';
import { join } from 'path';
import { existsSync, mkdirSync } from 'fs';
import type { ScreenshotParams, ScreenshotResult, PlatformScreenshot } from './types.js';
import { win32Platform } from './platform-win32.js';
import { darwinPlatform } from './platform-darwin.js';
import { linuxPlatform } from './platform-linux.js';
import { postProcess } from './post-process.js';

// ============================================================
// Constants
// ============================================================

const DEFAULT_FILENAME = 'aidex-screenshot.png';

// ============================================================
// Platform Selection
// ============================================================

function getPlatformImpl(): PlatformScreenshot {
    switch (process.platform) {
        case 'win32':
            return win32Platform;
        case 'darwin':
            return darwinPlatform;
        case 'linux':
            return linuxPlatform;
        default:
            throw new Error(`Unsupported platform: ${process.platform}. Supported: Windows, macOS, Linux.`);
    }
}

// ============================================================
// Synchronous Delay
// ============================================================

function sleepSync(ms: number): void {
    Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
}

// ============================================================
// Implementation
// ============================================================

export function screenshot(params: ScreenshotParams): ScreenshotResult {
    const mode = params.mode ?? 'fullscreen';

    // Validate mode-specific requirements
    if (mode === 'window' && !params.window_title) {
        return {
            success: false,
            file_path: '',
            mode,
            error: 'window_title is required when mode is "window". Use aidex_windows to find window titles.',
        };
    }

    if (mode === 'rect') {
        if (params.x === undefined || params.y === undefined || params.width === undefined || params.height === undefined) {
            return {
                success: false,
                file_path: '',
                mode,
                error: 'x, y, width, and height are all required when mode is "rect".',
            };
        }
        if (params.width <= 0 || params.height <= 0) {
            return {
                success: false,
                file_path: '',
                mode,
                error: 'width and height must be positive.',
            };
        }
    }

    // Validate scale
    if (params.scale !== undefined && (params.scale < 0.1 || params.scale > 1.0)) {
        return {
            success: false,
            file_path: '',
            mode,
            error: 'scale must be between 0.1 and 1.0',
        };
    }

    // Validate colors
    const validColors = [2, 4, 16, 256];
    if (params.colors !== undefined && !validColors.includes(params.colors)) {
        return {
            success: false,
            file_path: '',
            mode,
            error: `colors must be one of: ${validColors.join(', ')}`,
        };
    }

    // Resolve file path
    const dir = params.save_path ?? tmpdir();
    const filename = params.filename ?? DEFAULT_FILENAME;
    const filePath = join(dir, filename);

    // Ensure target directory exists
    if (!existsSync(dir)) {
        mkdirSync(dir, { recursive: true });
    }

    // Apply delay
    if (params.delay && params.delay > 0) {
        sleepSync(Math.round(params.delay * 1000));
    }

    try {
        const impl = getPlatformImpl();

        switch (mode) {
            case 'fullscreen':
                impl.captureFullscreen(filePath, params.monitor);
                break;
            case 'active_window':
                impl.captureActiveWindow(filePath);
                break;
            case 'window':
                impl.captureWindow(filePath, params.window_title!);
                break;
            case 'region':
                impl.captureRegion(filePath);
                break;
            case 'rect':
                impl.captureRect(filePath, params.x!, params.y!, params.width!, params.height!);
                break;
        }

        // Verify file was created
        if (!existsSync(filePath)) {
            return {
                success: false,
                file_path: filePath,
                mode,
                error: 'Screenshot file was not created. The capture may have been cancelled or the tool failed silently.',
            };
        }

        // Post-process: scale and/or color reduction
        const needsPostProcess = (params.scale !== undefined && params.scale < 1.0) || params.colors !== undefined;
        let original_size: number | undefined;
        let optimized_size: number | undefined;

        if (needsPostProcess) {
            try {
                const ppResult = postProcess(filePath, {
                    scale: params.scale,
                    colors: params.colors,
                });
                original_size = ppResult.original_size;
                optimized_size = ppResult.optimized_size;
            } catch (ppError) {
                // Post-processing failed — return the unmodified screenshot with a warning
                return {
                    success: true,
                    file_path: filePath,
                    mode,
                    monitor: params.monitor,
                    error: `Screenshot captured but post-processing failed: ${ppError instanceof Error ? ppError.message : String(ppError)}`,
                };
            }
        }

        return {
            success: true,
            file_path: filePath,
            mode,
            monitor: params.monitor,
            scale: params.scale,
            colors: params.colors,
            original_size,
            optimized_size,
        };
    } catch (error) {
        return {
            success: false,
            file_path: filePath,
            mode,
            error: error instanceof Error ? error.message : String(error),
        };
    }
}
