"""Transparent overlay to highlight a screen region. Win32 only.

Usage:
    python highlight.py <x> <y> <width> <height> [options]

Options:
    --color HEX      Border color (default: #00b8b1 — Adom teal)
    --duration MS     Auto-dismiss after N milliseconds (default: 5000)
    --label TEXT      Text badge above the highlight box
    --thickness N     Border thickness in pixels (default: 3)

Coordinates are in PHYSICAL pixels (matching DPI-aware screenshots).
On high-DPI displays (e.g., 150%), tkinter coordinates are logical, so
this tool scales from physical -> logical automatically.

The overlay is always-on-top and auto-dismisses after --duration ms.
Zero pip deps — uses only tkinter + ctypes.
"""

import argparse
import ctypes
import sys
import tkinter as tk

# Nearly-black color that Windows treats as transparent
_TRANSPARENT = "#010101"


def _get_dpi_scale():
    """Get the DPI scale factor using Win32 GetDeviceCaps.

    Compares physical screen resolution (from GetDeviceCaps) with the
    logical resolution (from GetSystemMetrics). Works WITHOUT calling
    SetProcessDPIAware, so the process stays DPI-unaware and Windows
    handles all rendering scaling for us.
    """
    try:
        user32 = ctypes.windll.user32
        gdi32 = ctypes.windll.gdi32

        # Logical screen size (what a DPI-unaware process sees)
        logical_w = user32.GetSystemMetrics(0)

        # Physical screen size (actual pixel count)
        hdc = user32.GetDC(0)
        physical_w = gdi32.GetDeviceCaps(hdc, 118)  # DESKTOPHORZRES
        user32.ReleaseDC(0, hdc)

        if logical_w > 0 and physical_w > 0:
            return physical_w / logical_w
        return 1.0
    except Exception:
        return 1.0


# NOTE: We intentionally do NOT call SetProcessDPIAware here.
# Tkinter works best as a DPI-unaware process: we convert physical
# input coords to logical, and Windows handles the rest.


def show_highlight(x, y, width, height, color="#00b8b1", duration=5000,
                   label="", thickness=3):
    """Show a colored border overlay at the given screen coordinates.

    Coordinates are in PHYSICAL pixels (matching DPI-aware screenshots).
    Internally converts to logical (DPI-unaware) coordinates for tkinter.
    """

    # Convert physical pixels -> logical pixels for DPI-unaware tkinter
    scale = _get_dpi_scale()
    x = int(x / scale)
    y = int(y / scale)
    width = int(width / scale)
    height = int(height / scale)

    pad = thickness + 2
    label_h = 26 if label else 0

    total_w = width + pad * 2
    total_h = height + pad * 2 + label_h

    root = tk.Tk()
    root.title("")
    root.overrideredirect(True)
    root.attributes("-topmost", True)
    root.attributes("-transparentcolor", _TRANSPARENT)
    root.configure(bg=_TRANSPARENT)
    root.geometry(f"{total_w}x{total_h}+{x - pad}+{y - pad - label_h}")

    canvas = tk.Canvas(
        root, bg=_TRANSPARENT, highlightthickness=0,
        width=total_w, height=total_h,
    )
    canvas.pack()

    # -- Main border rectangle
    ry = label_h
    canvas.create_rectangle(
        pad, ry + pad, width + pad, ry + height + pad,
        outline=color, width=thickness, tags="border",
    )

    # -- Corner accents (L-shaped marks for extra visibility)
    clen = max(12, min(24, width // 6, height // 6))
    thick2 = thickness + 2
    corners = [
        (pad, ry + pad, 1, 1),                      # top-left
        (width + pad, ry + pad, -1, 1),              # top-right
        (pad, ry + height + pad, 1, -1),             # bottom-left
        (width + pad, ry + height + pad, -1, -1),    # bottom-right
    ]
    for cx, cy, dx, dy in corners:
        canvas.create_line(cx, cy, cx + dx * clen, cy,
                           fill=color, width=thick2)
        canvas.create_line(cx, cy, cx, cy + dy * clen,
                           fill=color, width=thick2)

    # -- Label badge
    if label:
        badge_w = min(total_w, len(label) * 9 + 24)
        canvas.create_rectangle(0, 0, badge_w, label_h,
                                fill=color, outline="")
        canvas.create_text(
            badge_w // 2, label_h // 2, text=label,
            fill="white", font=("Segoe UI", 10, "bold"),
        )

    # -- Gentle pulse animation
    bright = _lighten(color, 0.35)
    pulse_state = [0]

    def pulse():
        if pulse_state[0] >= 6:
            return
        c = bright if pulse_state[0] % 2 == 0 else color
        canvas.itemconfig("border", outline=c)
        pulse_state[0] += 1
        root.after(350, pulse)

    root.after(200, pulse)

    # -- Auto-dismiss
    root.after(duration, root.destroy)
    root.mainloop()


def _lighten(hex_color, factor):
    """Lighten a hex color by factor (0-1)."""
    h = hex_color.lstrip("#")
    r, g, b = int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
    r = min(255, int(r + (255 - r) * factor))
    g = min(255, int(g + (255 - g) * factor))
    b = min(255, int(b + (255 - b) * factor))
    return f"#{r:02x}{g:02x}{b:02x}"


def main():
    parser = argparse.ArgumentParser(
        description="Show highlight overlay on screen")
    parser.add_argument("x", type=int, help="X position (pixels from left)")
    parser.add_argument("y", type=int, help="Y position (pixels from top)")
    parser.add_argument("width", type=int, help="Width of highlight region")
    parser.add_argument("height", type=int, help="Height of highlight region")
    parser.add_argument("--color", default="#00b8b1",
                        help="Border color (default: Adom teal)")
    parser.add_argument("--duration", type=int, default=5000,
                        help="Auto-dismiss after N ms (default: 5000)")
    parser.add_argument("--label", default="",
                        help="Text badge above the highlight")
    parser.add_argument("--thickness", type=int, default=3,
                        help="Border thickness in px (default: 3)")
    args = parser.parse_args()

    show_highlight(
        args.x, args.y, args.width, args.height,
        color=args.color, duration=args.duration,
        label=args.label, thickness=args.thickness,
    )


if __name__ == "__main__":
    main()
