# ~/.config/qtile/config.py
from typing import List, Any
qtile: Any
from libqtile import bar, layout, widget, hook
from libqtile.config import Key, Group, ScratchPad, Match, Screen, Drag, Click, DropDown
from libqtile.lazy import lazy
import subprocess, os

@hook.subscribe.startup_once
def set_wallpapers():
    import subprocess, os

    # 1. First, lock in your specific arandr monitor arrangement
    layout_script = os.path.expanduser("~/.config/qtile/monitor_setup.sh")
    if os.path.exists(layout_script):
        subprocess.call(["sh", layout_script])

    # 2. Let nitrogen seamlessly restore the independent scaled images
    # across your off-center screen arrangement
    subprocess.Popen(["nitrogen", "--restore"])

# ==================== MOD KEYS ====================
mod = "mod4"

# ==================== APPS ====================
# terminal = "xfce4-terminal"
terminal = "alacritty"
browser = "brave-browser-stable"

# ==================== COLORS ====================
colors = {
    "bg": "#282828",
    "fg": "#ebdbb2",
    "red": "#fb4934",
    "orange": "#fe8019",
    "yellow": "#fabd2f",
    "green": "#b8bb26",
    "aqua": "#8ec07c",
    "blue": "#83a598",
    "purple": "#d3869b",
    "muted": "#928374",
}

# ==================== KEYBINDINGS ====================
keys = [
    Key([mod], "Return", lazy.spawn(terminal), desc="Terminal"),
    Key([mod], "b", lazy.spawn(browser), desc="Browser"),
    Key([mod], "r", lazy.spawn("rofi -show drun"), desc="Rofi"),
    Key([mod, "shift"], "r", lazy.spawn("rofi -show run"), desc="Rofi"),

    Key([mod], "h", lazy.layout.left(), desc="Focus left"),
    Key([mod], "l", lazy.layout.right(), desc="Focus right"),
    Key([mod], "j", lazy.layout.down(), desc="Focus down"),
    Key([mod], "k", lazy.layout.up(), desc="Focus up"),

    Key([mod, "control"], "h", lazy.layout.shuffle_left(), desc="Shuffle left"),
    Key([mod, "control"], "l", lazy.layout.shuffle_right(), desc="Shuffle right"),
    Key([mod, "control"], "j", lazy.layout.shuffle_down(), desc="Shuffle down"),
    Key([mod, "control"], "k", lazy.layout.shuffle_up(), desc="Shuffle up"),

    # Resize bindings for MonadTall in Qtile 0.35
    Key([mod, "shift"], "k", lazy.layout.grow(), desc="Grow window"),
    Key([mod, "shift"], "j", lazy.layout.shrink(), desc="Shrink window"),
    Key([mod, "shift"], "h", lazy.layout.grow_main(), desc="Grow main pane"),
    Key([mod, "shift"], "l", lazy.layout.shrink_main(), desc="Shrink main pane"),
    Key([mod], "n", lazy.layout.normalize(), desc="Reset all sizes"),

    Key([mod, "shift"], "q", lazy.window.kill(), desc="Kill window"),
    Key([mod], "f", lazy.window.toggle_fullscreen(), desc="Toggle fullscreen"),
    Key([mod], "space", lazy.next_layout(), desc="Next layout"),

    Key([mod, "control"], "r", lazy.restart(), desc="Restart Qtile"),
    Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"),

    # Volume Control
    Key([], "XF86AudioRaiseVolume", lazy.spawn("pactl set-sink-volume @DEFAULT_SINK@ +3%")),
    Key([], "XF86AudioLowerVolume", lazy.spawn("pactl set-sink-volume @DEFAULT_SINK@ -3%")),
    Key([], "XF86AudioMute", lazy.spawn("pactl set-sink-mute @DEFAULT_SINK@ toggle")),

    # Quake alacritty
    Key(["mod1"], "1", lazy.group['scratch'].dropdown_toggle('quake'), desc="Toggle quake dropdown"),

    # Lock screen
    Key(["control", "mod1"], "l", lazy.spawn("sh -c 'light-locker-command -l'"), desc="Lock screen"),

    # Switch focus between physical monitors natively
    Key([mod], "o", lazy.next_screen(), desc="Move focus to next screen"),
    Key([mod], "i", lazy.prev_screen(), desc="Move focus to previous screen"),

    # Simple shift right (l) and left (h)
    Key([mod, "control", "shift"], "l",
        lazy.window.function(lambda w: w.togroup(str(int(w.group.name) + 1), switch_group=True) if int(w.group.name) < 6 else None),
        desc="Shift window right"),
    Key([mod, "control", "shift"], "h",
        lazy.window.function(lambda w: w.togroup(str(int(w.group.name) - 1), switch_group=True) if int(w.group.name) > 1 else None),
        desc="Shift window left"),
]

# ==================== GROUPS ====================
group_names = ["1", "2", "3", "4", "5", "6", "7", "8"]
groups = [Group(i) for i in group_names]

groups.append(
    ScratchPad("scratch", [
        DropDown(
            "quake",
            # "alacritty --class alacritty",
            "alacritty --class Alacritty",
            width=1,
            height=1,
            x=0,
            y=0,
            opacity=.96,
            on_focus_lost_hide=True,
        )
    ])
)


# for i, g in enumerate(groups, 1):
#     keys.append(Key([mod], str(i), lazy.group[g.name].toscreen()))
#     keys.append(Key([mod, "shift"], str(i), lazy.window.togroup(g.name, switch_group=True)))
# ==================== KEYBINDINGS FOR GROUPS ====================
for g in groups:
    # Skip the scratchpad so it doesn't break our number math
    if g.name == "scratch":
        continue

    keys.extend([
        # Mod + [1-5] = Switch to workspace
        Key([mod], g.name, lazy.group[g.name].toscreen(),
            desc=f"Switch to group {g.name}"),

        # Mod + Shift + [1-5] = Move window to workspace
        Key([mod, "shift"], g.name, lazy.window.togroup(g.name, switch_group=True),
            desc=f"Move window to group {g.name}"),
    ])

# ==================== LAYOUTS ====================
layouts = [
    layout.MonadWide(
        margin=8,
        border_focus=colors["blue"],
        border_normal=colors["muted"],
        border_width=2,
        ratio=0.6,
    ),
    layout.Max(),
    layout.Floating(),
    layout.MonadTall(
        margin=8,
        border_focus=colors["blue"],
        border_normal=colors["muted"],
        border_width=2,
        ratio=0.6,
    ),
    layout.Max(),
    layout.Floating(),
]

floating_layout = layout.Floating(
    float_rules=[
        *layout.Floating.default_float_rules,
        Match(wm_type="dialog"),
        Match(title="Confirmation"),
    ]
)

# ==================== WIDGET DEFAULTS ====================
widget_defaults = dict(
    font="DejaVu Sans Mono",
    fontsize=13,
    padding=6,
    background=colors["bg"],
    foreground=colors["fg"],
)

# ==================== SCREENS ====================
screens = [
    # Screen 0: Primary Laptop Display
    Screen(
        top=bar.Bar(
            [
                widget.GroupBox(
                    font="DejaVu Sans Mono Bold",
                    fontsize=13,
                    margin_x=4,
                    padding_x=8,
                    padding_y=4,
                    active=colors["fg"],
                    inactive=colors["muted"],
                    highlight_method="line",
                    this_current_screen_border=colors["yellow"],
                    urgent_border=colors["red"],
                    rounded=False,
                    background=colors["bg"],
                ),
                widget.Sep(linewidth=1, padding=12, foreground=colors["muted"], background=colors["bg"]),
                widget.CurrentLayout(
                    scale=0.7,
                    padding=8,
                    foreground=colors["fg"],
                    background=colors["bg"],
                ),
                # widget.WindowName(
                #     padding=10,
                #     max_chars=60,
                #     background=colors["bg"]
                # ),
                widget.Spacer(background=colors["bg"]),
                widget.CPU(
                    format='CPU: {load_percent}%',
                    foreground=colors["orange"],
                    background=colors["bg"]
                ),
                widget.Memory(
                    format='RAM: {MemUsed:.0f}M',
                    foreground=colors["aqua"],
                    background=colors["bg"]
                ),
                widget.Sep(linewidth=1, padding=12, foreground=colors["muted"], background=colors["bg"]),
                widget.Volume(
                    format='Vol: {volume}%',
                    foreground=colors["purple"],
                    background=colors["bg"],
                    padding=8,
                    update_interval=2,
                    unmute_format='Vol: {volume}%',
                    mute_format='Muted',
                    mouse_callbacks={
                        'Button3': lazy.spawn('pavucontrol')  # right-click -> open pavucontrol
                    }
                ),
                widget.Sep(linewidth=1, padding=12, foreground=colors["muted"], background=colors["bg"]),
                widget.GenPollText(
                    func=lambda: subprocess.check_output(
                        "echo '🔋 Bat: '$(cat /sys/class/power_supply/BAT0/capacity)'%' $(cat /sys/class/power_supply/BAT0/status | sed 's/Charging/↑/;s/Discharging/↓/;s/Full/⚡/')",
                        shell=True, text=True
                    ).strip(),
                    update_interval=5,
                    foreground=colors["green"],
                    background=colors["bg"],
                    padding=8,
                ),
                widget.Sep(linewidth=1, padding=12, foreground=colors["muted"], background=colors["bg"]),
                widget.Clock(
                    format="%Y-%m-%d %a %I:%M %p",
                    foreground=colors["yellow"],
                    padding=10,
                    background=colors["bg"]
                ),
                widget.Systray(
                    padding=8,
                    icon_size=18,
                    background=colors["bg"]
                ),
            ],
            size=28,
            background=colors["bg"],
            margin=[0, 0, 0, 0],
            opacity=1.0,
        ),
    ),
    # Screen 1: External Monitor Display
    Screen(
        top=bar.Bar(
            [
                widget.GroupBox(
                    font="DejaVu Sans Mono Bold",
                    fontsize=13,
                    margin_x=4,
                    padding_x=8,
                    padding_y=4,
                    active=colors["fg"],
                    inactive=colors["muted"],
                    highlight_method="line",
                    this_current_screen_border=colors["yellow"],
                    urgent_border=colors["red"],
                    rounded=False,
                    background=colors["bg"],
                ),
                widget.Sep(linewidth=1, padding=12, foreground=colors["muted"], background=colors["bg"]),
                widget.CurrentLayout(
                    scale=0.7,
                    padding=8,
                    foreground=colors["fg"],
                    background=colors["bg"],
                ),
                # widget.WindowName(
                #     padding=10,
                #     max_chars=60,
                #     background=colors["bg"]
                # ),
                widget.Spacer(background=colors["bg"]),
                widget.Clock(
                    format="%Y-%m-%d %a %I:%M %p",
                    foreground=colors["yellow"],
                    padding=10,
                    background=colors["bg"]
                ),
            ],
            size=28,
            background=colors["bg"],
            margin=[0, 0, 0, 0],
            opacity=1.0,
        ),
    )
]

# ==================== MOUSE ====================
mouse = [
    Drag([mod], "Button1", lazy.window.set_position_floating(), start=lazy.window.get_position()),
    Drag([mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size()),

    Click([mod], "Button2", lazy.window.bring_to_front()),
]

# ==================== SETTINGS ====================
dgroups_key_binder = None
dgroups_app_rules: List = []
follow_mouse_focus = True
bring_front_click = False
cursor_warp = True
auto_fullscreen = True
focus_on_window_activation = "smart"
wmname = "LG3D"

# ==================== AUTOSTART ====================
@hook.subscribe.startup_once
def autostart():
    script = os.path.expanduser("~/.config/qtile/autostart.sh")
    if os.path.exists(script):
        subprocess.Popen([script])
