#!/usr/bin/env python3
"""
Active window geometry helper.

Provides cross-platform detection of the currently focused window's
position and size using native OS APIs (xprop/xwininfo on Linux,
win32gui on Windows, AppleScript on macOS). Does NOT use OCR.
"""

import platform
import subprocess
from typing import Optional, Dict

from ws_package.log.writer import LogWriter

logger = LogWriter.file(__name__)


def get_active_window_geometry() -> Optional[Dict]:
    """Get active window geometry.

    Returns a dict with keys 'X', 'Y', 'WIDTH', 'HEIGHT' (ints), or None
    if geometry could not be determined.
    """
    system = platform.system()
    try:
        if system == "Linux":
            return _get_linux_window_geometry()
        elif system == "Windows":
            return _get_windows_window_geometry()
        elif system == "Darwin":
            return _get_mac_window_geometry()
        else:
            logger.warning("Unsupported platform: %s", system)
            return None
    except Exception as e:
        logger.error("Error getting window geometry: %s", e)
        return None


def _get_linux_window_geometry() -> Optional[Dict]:
    """Get window geometry on Linux using xprop / xwininfo."""
    try:
        # Get active window ID
        result = subprocess.run(
            ['xprop', '-root', '_NET_ACTIVE_WINDOW'],
            capture_output=True, text=True, timeout=5
        )

        if result.returncode != 0:
            return None

        window_id = result.stdout.strip().split()[-1]

        # Get window geometry
        geo_result = subprocess.run(
            ['xprop', '-id', window_id, 'WM_NORMAL_HINTS'],
            capture_output=True, text=True, timeout=5
        )

        if geo_result.returncode != 0:
            # Fallback to get window position
            pos_result = subprocess.run(
                ['xwininfo', '-id', window_id],
                capture_output=True, text=True, timeout=5
            )

            if pos_result.returncode == 0:
                lines = pos_result.stdout.split('\n')
                geometry = {}
                for line in lines:
                    if 'Absolute upper-left X:' in line:
                        geometry['X'] = int(line.split(':')[1].strip())
                    elif 'Absolute upper-left Y:' in line:
                        geometry['Y'] = int(line.split(':')[1].strip())
                    elif 'Width:' in line:
                        geometry['WIDTH'] = int(line.split(':')[1].strip())
                    elif 'Height:' in line:
                        geometry['HEIGHT'] = int(line.split(':')[1].strip())

                if all(key in geometry for key in ['X', 'Y', 'WIDTH', 'HEIGHT']):
                    return geometry

            return None

        # Parse WM_NORMAL_HINTS output
        output = geo_result.stdout
        geometry = {}

        if 'program specified size' in output:
            size_match = output.split('program specified size')[1].split()[0:2]
            if len(size_match) >= 2:
                geometry['WIDTH'] = int(size_match[0])
                geometry['HEIGHT'] = int(size_match[1])

        # Get window position
        pos_result = subprocess.run(
            ['xwininfo', '-id', window_id],
            capture_output=True, text=True, timeout=5
        )

        if pos_result.returncode == 0:
            lines = pos_result.stdout.split('\n')
            for line in lines:
                if 'Absolute upper-left X:' in line:
                    geometry['X'] = int(line.split(':')[1].strip())
                elif 'Absolute upper-left Y:' in line:
                    geometry['Y'] = int(line.split(':')[1].strip())

        if all(key in geometry for key in ['X', 'Y', 'WIDTH', 'HEIGHT']):
            return geometry

        return None

    except Exception as e:
        logger.error("Error getting Linux window geometry: %s", e)
        return None


def _get_windows_window_geometry() -> Optional[Dict]:
    """Get window geometry on Windows using win32gui."""
    try:
        import win32gui

        hwnd = win32gui.GetForegroundWindow()
        rect = win32gui.GetWindowRect(hwnd)

        return {
            'X': rect[0],
            'Y': rect[1],
            'WIDTH': rect[2] - rect[0],
            'HEIGHT': rect[3] - rect[1]
        }

    except ImportError:
        logger.warning("win32gui not available for Windows")
        return None
    except Exception as e:
        logger.error("Error getting Windows window geometry: %s", e)
        return None


def _get_mac_window_geometry() -> Optional[Dict]:
    """Get window geometry on macOS using AppleScript."""
    try:
        script = '''
        tell application "System Events"
            try
                set frontmostApp to first application process whose frontmost is true
                set windowBounds to bounds of first window of frontmostApp
                return (item 1 of windowBounds) & "," & (item 2 of windowBounds) & "," & ((item 3 of windowBounds) - (item 1 of windowBounds)) & "," & ((item 4 of windowBounds) - (item 2 of windowBounds))
            on error
                return "0,0,0,0"
            end try
        end tell
        '''

        result = subprocess.run(
            ['osascript', '-e', script],
            capture_output=True, text=True, timeout=5
        )

        if result.returncode == 0:
            coords = result.stdout.strip().split(',')
            if len(coords) >= 4:
                return {
                    'X': int(coords[0]),
                    'Y': int(coords[1]),
                    'WIDTH': int(coords[2]),
                    'HEIGHT': int(coords[3])
                }

        return None

    except Exception as e:
        logger.error("Error getting macOS window geometry: %s", e)
        return None
