"""Mengumpulkan info sistem: jendela aktif, daftar jendela, daftar proses."""
import collections
import platform
import socket
import sys

try:
    import psutil
except ImportError:  # psutil opsional di luar Windows
    psutil = None

IS_WIN = sys.platform == "win32"

if IS_WIN:
    import ctypes
    from ctypes import wintypes

    user32 = ctypes.windll.user32


def hostname():
    return socket.gethostname()


def os_name():
    return platform.platform()[:64]


def _process_name(pid):
    if psutil is None:
        return ""
    try:
        return psutil.Process(pid).name()
    except Exception:
        return ""


def _window_title(hwnd):
    length = user32.GetWindowTextLengthW(hwnd)
    if length <= 0:
        return ""
    buf = ctypes.create_unicode_buffer(length + 1)
    user32.GetWindowTextW(hwnd, buf, length + 1)
    return buf.value


def get_active_window():
    """Return (judul_jendela, nama_proses) untuk jendela yang sedang di depan."""
    if not IS_WIN:
        return "", ""
    hwnd = user32.GetForegroundWindow()
    if not hwnd:
        return "", ""
    pid = wintypes.DWORD()
    user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
    return _window_title(hwnd), _process_name(pid.value)


def list_windows(limit=80):
    """Semua jendela yang terlihat dan punya judul."""
    if not IS_WIN:
        return []
    found = []
    enum_proc = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)

    def callback(hwnd, _lparam):
        if user32.IsWindowVisible(hwnd):
            title = _window_title(hwnd)
            if title and title != "Program Manager":
                pid = wintypes.DWORD()
                user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
                found.append({"title": title[:200], "process": _process_name(pid.value)})
        return True

    user32.EnumWindows(enum_proc(callback), 0)
    return found[:limit]


def list_processes(limit=150):
    """Proses yang berjalan, digabung per nama: [{name, count}], terbanyak dulu."""
    if psutil is None:
        return []
    counter = collections.Counter()
    for proc in psutil.process_iter(["name"]):
        name = proc.info.get("name")
        if name:
            counter[name] += 1
    return [{"name": n, "count": c} for n, c in sorted(counter.items(), key=lambda x: (-x[1], x[0].lower()))][:limit]
