import subprocess
import json

import config.data as data

def get_current_workspace():
    """
    Get the current workspace ID using hyprctl.
    """
    try:
        result = subprocess.run(
            ["hyprctl", "activeworkspace"],
            capture_output=True,
            text=True
        )
        # Assume the output similar to: "ID <number>"
        # Extracting the number from the output
        parts = result.stdout.split()
        for i, part in enumerate(parts):
            if part == "ID" and i + 1 < len(parts):
                return int(parts[i+1])
    except Exception as e:
        print(f"Error getting current workspace: {e}")
    return -1

def get_screen_dimensions():
    """
    Get screen dimensions from hyprctl.
    
    Returns:
        tuple: (width, height) of the monitor containing the current workspace
    """
    try:
        # Get current workspace
        workspace_id = get_current_workspace()
        
        # Get monitor information
        result = subprocess.run(
            ["hyprctl", "-j", "monitors"],
            capture_output=True,
            text=True
        )
        monitors = json.loads(result.stdout)
        
        # Find the monitor containing our workspace
        for monitor in monitors:
            if monitor.get("activeWorkspace", {}).get("id") == workspace_id:
                return monitor.get("width", data.CURRENT_WIDTH), monitor.get("height", data.CURRENT_HEIGHT)
                
        # Fallback to first monitor
        if monitors:
            return monitors[0].get("width", data.CURRENT_WIDTH), monitors[0].get("height", data.CURRENT_HEIGHT)
    except Exception as e:
        print(f"Error getting screen dimensions: {e}")
    
    # Default fallback values
    return data.CURRENT_WIDTH, data.CURRENT_HEIGHT

def check_occlusion(occlusion_region, workspace=None):
    """
    Check if a region is occupied by any window on a given workspace.

    Parameters:
        occlusion_region: Can be one of:
            - tuple (side, size): where side is "top", "bottom", "left", or "right"
              and size is the pixel width of the region
            - tuple (x, y, width, height): The full region coordinates (legacy format)
        workspace (int, optional): The workspace ID to check. If None, the current workspace is used.

    Returns:
        bool: True if any window overlaps with the occlusion region, False otherwise.
    """
    if workspace is None:
        workspace = get_current_workspace()
    
    # Handle simplified side-based format
    if isinstance(occlusion_region, tuple) and len(occlusion_region) == 2:
        side, size = occlusion_region
        if isinstance(side, str):
            # Convert side-based format to coordinates
            screen_width, screen_height = get_screen_dimensions()
            
            if side.lower() == "bottom":
                occlusion_region = (0, screen_height - size, screen_width, size)
            elif side.lower() == "top":
                occlusion_region = (0, 0, screen_width, size)
            elif side.lower() == "left":
                occlusion_region = (0, 0, size, screen_height)
            elif side.lower() == "right":
                occlusion_region = (screen_width - size, 0, size, screen_height)
    
    # Ensure occlusion_region is in the correct format (x, y, width, height)
    if not isinstance(occlusion_region, tuple) or len(occlusion_region) != 4:
        print(f"Invalid occlusion region format: {occlusion_region}")
        return False

    try:
        result = subprocess.run(
            ["hyprctl", "-j", "clients"],
            capture_output=True,
            text=True
        )
        clients = json.loads(result.stdout)
    except Exception as e:
        print(f"Error retrieving client windows: {e}")
        return False

    occ_x, occ_y, occ_width, occ_height = occlusion_region
    occ_x2 = occ_x + occ_width
    occ_y2 = occ_y + occ_height

    # Get screen dimensions for fullscreen check
    screen_width, screen_height = get_screen_dimensions()

    for client in clients:
        # Check if client is mapped
        if not client.get("mapped", False):
            continue

        # Ensure client has proper workspace information and matches the workspace
        client_workspace = client.get("workspace", {})
        if client_workspace.get("id") != workspace:
            continue

        # Ensure client has position and size info
        position = client.get("at")
        size = client.get("size")
        if not position or not size:
            continue

        x, y = position
        width, height = size
        win_x1, win_y1 = x, y
        win_x2, win_y2 = x + width, y + height

        # Check for fullscreen windows (size matches screen and positioned at 0,0)
        if (width, height) == (screen_width, screen_height) and (x, y) == (0, 0):
            # For fullscreen windows, check if occlusion region is the top area
            if occ_y == 0 and occ_height > 0:  # Top region
                return True  # Consider fullscreen as occluding the top

        # Check for intersection between the window and occlusion region
        if not (win_x2 <= occ_x or win_x1 >= occ_x2 or win_y2 <= occ_y or win_y1 >= occ_y2):
            return True  # Occlusion region is occupied

    return False  # No window overlaps the occlusion region
