"""
Quan ly vong doi Chrome.

LOGIN MODE   : Mo Chrome binh thuong bang subprocess (khong co Playwright).
AUTOMATE MODE: Mo Chrome bang subprocess voi --remote-debugging-port,
               sau do Playwright ket noi qua CDP.
=> Khong co banner "controlled by automated software".
"""
from __future__ import annotations

import socket
import subprocess
import time
from pathlib import Path

from .constants import (
    CHROME_BINARY,
    CDP_PORT_BASE,
    CHROME_LAUNCH_TIMEOUT_SEC,
    BROWSER_SLOW_MO,
    SORA_URL,
)


# ---------------------------------------------------------------------------
# Internal helpers
# ---------------------------------------------------------------------------

def _wait_for_cdp(port: int, proc: subprocess.Popen, timeout: float = 30.0) -> None:
    """Block cho den khi Chrome mo cong CDP, kiem tra process con song."""
    deadline = time.time() + timeout
    while time.time() < deadline:
        # Neu Chrome thoat som thi bao loi ngay
        ret = proc.poll()
        if ret is not None:
            stderr_out = ""
            if proc.stderr:
                stderr_out = proc.stderr.read().decode(errors="replace")[:500]
            raise RuntimeError(
                f"Chrome thoat ngay lap tuc (exit code {ret}).\n"
                f"Stderr: {stderr_out or '(trong)'}"
            )
        try:
            with socket.create_connection(("127.0.0.1", port), timeout=1):
                return
        except OSError:
            time.sleep(0.4)
    # Het timeout — lay stderr de debug
    stderr_out = ""
    if proc.stderr:
        stderr_out = proc.stderr.read().decode(errors="replace")[:500]
    raise TimeoutError(
        f"Chrome khong mo cong CDP {port} sau {timeout}s.\n"
        f"Stderr: {stderr_out or '(trong)'}\n"
        "Thu tat tat ca Chrome dang mo roi chay lai."
    )


def _spawn_chrome(
    profile_path: Path,
    *,
    debug_port: int | None = None,
    url: str | None = None,
) -> subprocess.Popen:
    cmd = [
        CHROME_BINARY,
        f"--user-data-dir={profile_path}",
        "--no-first-run",
        "--no-default-browser-check",
        "--mute-audio",
        "--disable-features=OptimizationGuideModelDownloading",
    ]
    if debug_port:
        cmd.append(f"--remote-debugging-port={debug_port}")
    if url:
        cmd.append(url)
    print(f"  [chrome] CMD: {' '.join(cmd[:4])} ...")
    return subprocess.Popen(
        cmd,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.PIPE,  # capture de debug
    )


# ---------------------------------------------------------------------------
# Login mode
# ---------------------------------------------------------------------------

def launch_chrome_for_login(profile_path: Path, url: str | None = None) -> subprocess.Popen:
    """Mo mot cua so Chrome thong thuong de user dang nhap thu cong."""
    print(f"  [chrome] Mo profile: {profile_path.name} ...")
    return _spawn_chrome(profile_path, url=url)


# ---------------------------------------------------------------------------
# Automate mode
# ---------------------------------------------------------------------------

def _remove_singleton_lock(profile_path: Path) -> None:
    """Xoa file khoa con lai neu Chrome bi tat dot ngot lan truoc."""
    lock = profile_path / "SingletonLock"
    if lock.exists():
        lock.unlink()
        print(f"  [chrome] Da xoa SingletonLock cu: {lock}")


def launch_chrome_for_automation(
    profile_path: Path,
    debug_port: int,
    timeout: float = 30.0,
) -> tuple:
    """
    Mo Chrome voi cong CDP va ket noi Playwright qua CDP.
    Tra ve (proc, playwright, browser, context, page).
    Caller phai goi pw.stop() va close_chrome(proc) khi xong.
    """
    from playwright.sync_api import sync_playwright

    profile_name = profile_path.name
    _remove_singleton_lock(profile_path)

    print(f"  [chrome] Khoi dong: {profile_name} (port {debug_port}) ...")
    proc = _spawn_chrome(profile_path, debug_port=debug_port, url=SORA_URL)

    print(f"  [chrome] Cho CDP san sang (port {debug_port}) ...")
    _wait_for_cdp(debug_port, proc=proc, timeout=timeout)

    print(f"  [chrome] Ket noi Playwright ...")
    pw = sync_playwright().start()
    browser = pw.chromium.connect_over_cdp(
        f"http://127.0.0.1:{debug_port}",
        slow_mo=BROWSER_SLOW_MO,
    )
    context = browser.contexts[0] if browser.contexts else browser.new_context()
    page = context.pages[0] if context.pages else context.new_page()

    print(f"  [chrome] San sang: {profile_name}")
    return proc, pw, browser, context, page


def close_chrome(proc: subprocess.Popen) -> None:
    """Tat Chrome mot cach an toan."""
    proc.terminate()
    try:
        proc.wait(timeout=5)
    except subprocess.TimeoutExpired:
        proc.kill()
