from datetime import datetime
import ctypes
import threading
import time

import pyautogui
import pygetwindow as gw

BROWSER_KEYWORDS = [
    "google chrome",
    "microsoft edge",
    "mozilla firefox",
]

_discord_muted = True
_discord_mute_lock = threading.Lock()


def log(level, message):
    now = datetime.now().strftime("%H:%M:%S")
    print(f"[{level}] {now} {message}", flush=True)


def findDiscordWindow():
    candidates = []

    for window in gw.getAllWindows():
        title = (window.title or "").strip()
        if not title:
            continue
        if "discord" not in title.lower():
            continue
        candidates.append(window)

    if not candidates:
        raise RuntimeError("Discordウィンドウが見つかりません")

    candidates.sort(key=lambda window: -(window.width * window.height))
    return candidates[0]


def findBrowserWindow():
    candidates = []

    for window in gw.getAllWindows():
        title = (window.title or "").strip()
        if not title:
            continue
        lowered = title.lower()
        if not any(keyword in lowered for keyword in BROWSER_KEYWORDS):
            continue
        candidates.append(window)

    if not candidates:
        raise RuntimeError("ブラウザウィンドウが見つかりません")

    candidates.sort(key=lambda window: -(window.width * window.height))
    return candidates[0]


def findDiscordBrowserWindow():
    candidates = []

    for window in gw.getAllWindows():
        title = (window.title or "").strip()
        if not title:
            continue
        lowered = title.lower()
        if "discord" not in lowered:
            continue
        if not any(keyword in lowered for keyword in BROWSER_KEYWORDS):
            continue
        candidates.append(window)

    if not candidates:
        return None

    candidates.sort(key=lambda window: -(window.width * window.height))
    return candidates[0]


def activateDiscordWindow():
    window = findDiscordWindow()
    hwnd = getattr(window, "_hWnd", None)

    try:
        if window.isMinimized:
            window.restore()
    except Exception:
        pass

    if hwnd:
        try:
            ctypes.windll.user32.ShowWindow(hwnd, 9)
        except Exception:
            pass

    try:
        window.activate()
    except Exception as e:
        log("ERROR", f"Discord activate() failed detail={e}")

    if hwnd:
        try:
            ctypes.windll.user32.BringWindowToTop(hwnd)
            ctypes.windll.user32.SetForegroundWindow(hwnd)
        except Exception as e:
            log("ERROR", f"Discord SetForegroundWindow failed detail={e}")

    time.sleep(0.15)

    log("INFO", f"Discord window title={window.title}")
    return window


def findVrchatWindow():
    candidates = []

    for window in gw.getAllWindows():
        title = (window.title or "").strip()
        if not title:
            continue
        lowered = title.lower()
        if lowered == "vrchat":
            candidates.append((0, window))
            continue
        if lowered.startswith("vrchat "):
            candidates.append((1, window))
            continue
        if lowered.startswith("vrchat"):
            candidates.append((2, window))

    if not candidates:
        raise RuntimeError("VRChatウィンドウが見つかりません")

    candidates.sort(key=lambda item: (item[0], -(item[1].width * item[1].height)))
    return candidates[0][1]


def activateWindow(window, label):
    if not window:
        return

    hwnd = getattr(window, "_hWnd", None)

    try:
        if window.isMinimized:
            window.restore()
    except Exception:
        pass

    if hwnd:
        try:
            ctypes.windll.user32.ShowWindow(hwnd, 9)
        except Exception:
            pass

    try:
        window.activate()
    except Exception as e:
        log("ERROR", f"{label} activate() failed detail={e}")

    if hwnd:
        try:
            ctypes.windll.user32.BringWindowToTop(hwnd)
            ctypes.windll.user32.SetForegroundWindow(hwnd)
        except Exception as e:
            log("ERROR", f"{label} SetForegroundWindow failed detail={e}")

    time.sleep(0.15)
    try:
        pyautogui.click(window.left + window.width // 2, window.top + window.height // 2)
    except Exception:
        pass
    time.sleep(0.1)
    log("INFO", f"{label} window title={window.title}")


def setDiscordMute():
    log("ACTION", "setDiscordMute called")
    try:
        activateDiscordWindow()
    except Exception as e:
        log("ERROR", f"Discord window unavailable detail={e}")
        browser = findDiscordBrowserWindow() or findBrowserWindow()
        activateWindow(browser, "Browser")
    log("INFO", "Discord hotkey Ctrl+Shift+M")
    pyautogui.hotkey("ctrl", "shift", "m")
    activateWindow(findVrchatWindow(), "VRChat")


def setDiscordMuted(muted):
    global _discord_muted

    muted = bool(muted)

    with _discord_mute_lock:
        if _discord_muted == muted:
            log("INFO", f"Discord mute already {'on' if muted else 'off'}")
            return

        setDiscordMute()
        _discord_muted = muted
