"""macOS menu bar icon for AI Interview Assistant.

Lightweight process — shows an icon in the top bar with a dropdown menu.
No dock icon. Communicates with the daemon via HTTP and spawns the GUI as needed.

Usage (internal): python -m ai_interview.menubar
       or:        ai-interview menubar
"""

from __future__ import annotations

import json
import os
import subprocess
import sys
import threading
import urllib.request
from pathlib import Path

import objc
from AppKit import (
    NSApplication,
    NSApplicationActivationPolicyAccessory,
    NSImage,
    NSMenu,
    NSMenuItem,
    NSObject,
    NSStatusBar,
    NSVariableStatusItemLength,
)
from PyObjCTools import AppHelper

from ai_interview.config import load_saved_config

_PID_FILE = Path.home() / ".ai-interview-menubar.pid"
_GUI_PID_FILE = Path.home() / ".ai-interview-gui.pid"


def _is_running(pid: int) -> bool:
    try:
        os.kill(pid, 0)
        return True
    except (OSError, ProcessLookupError):
        return False


def _daemon_running(port: int = 7890) -> bool:
    try:
        req = urllib.request.Request(f"http://127.0.0.1:{port}/health")
        urllib.request.urlopen(req, timeout=1)
        return True
    except Exception:
        return False


def _cli_path() -> str:
    """Find the ai-interview CLI binary."""
    p = Path(sys.executable).parent / "ai-interview"
    if p.exists():
        return str(p)
    import shutil
    return shutil.which("ai-interview") or "ai-interview"


MENUBAR_ICONS = {
    "AI": ("AI", "AI ●"),
    "◆": ("◆", "◆"),
    "⚡": ("⚡", "⚡"),
    "●": ("●", "●"),
    "▶": ("▶", "▶"),
    "☰": ("☰", "☰"),
}


class MenuBarDelegate(NSObject):
    def applicationDidFinishLaunching_(self, notification):
        config = load_saved_config()
        self._port = int(config.get("port", 7890))
        self._cli = _cli_path()
        icon_key = config.get("menubar_icon", "●")
        self._icon_idle, self._icon_active = MENUBAR_ICONS.get(icon_key, MENUBAR_ICONS["AI"])

        # Create status bar item
        self.status_item = NSStatusBar.systemStatusBar().statusItemWithLength_(
            NSVariableStatusItemLength
        )
        self.status_item.setTitle_(self._icon_idle)
        self.status_item.setHighlightMode_(True)

        # Build menu
        self._menu = NSMenu.alloc().init()

        from ai_interview.i18n import t, set_language
        set_language(load_saved_config().get("gui_language", "en"))

        self._item_open_gui = self._add_item(t("menu_open_dashboard"), "openGui:")
        self._menu.addItem_(NSMenuItem.separatorItem())
        self._item_start = self._add_item(t("menu_start_interview"), "startInterview:")
        self._item_stop = self._add_item(t("menu_stop_interview"), "stopInterview:")
        self._item_stop.setEnabled_(False)
        self._item_restart = self._add_item(t("menu_restart"), "restartInterview:")
        self._item_restart.setEnabled_(False)
        self._menu.addItem_(NSMenuItem.separatorItem())
        self._add_item(t("menu_quit"), "quit:")

        self.status_item.setMenu_(self._menu)

        # Start status polling
        self._poll_thread = threading.Thread(target=self._poll_loop, daemon=True)
        self._poll_thread.start()

    def _add_item(self, title: str, action: str) -> NSMenuItem:
        item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(title, action, "")
        item.setTarget_(self)
        self._menu.addItem_(item)
        return item

    def _poll_loop(self):
        while True:
            running = _daemon_running(self._port)
            try:
                self.performSelectorOnMainThread_withObject_waitUntilDone_(
                    "updateStatus:", running, False
                )
            except Exception:
                pass
            threading.Event().wait(5)

    @objc.python_method
    def _update_status_impl(self, running):
        if running:
            self.status_item.setTitle_(self._icon_active)
            self._item_start.setEnabled_(False)
            self._item_stop.setEnabled_(True)
            self._item_restart.setEnabled_(True)
        else:
            self.status_item.setTitle_(self._icon_idle)
            self._item_start.setEnabled_(True)
            self._item_stop.setEnabled_(False)
            self._item_restart.setEnabled_(False)

    def updateStatus_(self, running):
        self._update_status_impl(running)

    def openGui_(self, sender):
        # Check if GUI is already open
        if _GUI_PID_FILE.exists():
            try:
                pid = int(_GUI_PID_FILE.read_text().strip())
                if _is_running(pid):
                    # Bring the Flet window to front by activating Flet.app
                    try:
                        from AppKit import NSWorkspace
                        for app in NSWorkspace.sharedWorkspace().runningApplications():
                            name = app.localizedName() or ""
                            bid = app.bundleIdentifier() or ""
                            if "Flet" in name or "AI Interview" in name or "flet" in bid:
                                app.activateWithOptions_(1 << 1)
                                break
                    except Exception:
                        pass
                    return
            except Exception:
                pass
        subprocess.Popen(
            [self._cli, "gui"],
            start_new_session=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            stdin=subprocess.DEVNULL,
        )

    def startInterview_(self, sender):
        # Start daemon directly with saved config (no GUI needed)
        from ai_interview.daemon import is_process_running, kill_existing, read_pid
        pid = read_pid()
        if pid and is_process_running(pid):
            return  # already running
        subprocess.Popen(
            [self._cli, "start", "--daemon"],
            start_new_session=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            stdin=subprocess.DEVNULL,
        )
        # Start watchdog too
        subprocess.Popen(
            [self._cli, "_watchdog"],
            start_new_session=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            stdin=subprocess.DEVNULL,
        )

    def stopInterview_(self, sender):
        subprocess.Popen(
            [self._cli, "stop"],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
        )

    def restartInterview_(self, sender):
        subprocess.Popen(
            [self._cli, "restart"],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
        )

    def quit_(self, sender):
        _PID_FILE.unlink(missing_ok=True)
        NSApplication.sharedApplication().terminate_(sender)


def run_menubar() -> None:
    """Start the menu bar icon. Blocks until quit."""
    # Prevent duplicates
    if _PID_FILE.exists():
        try:
            old_pid = int(_PID_FILE.read_text().strip())
            if _is_running(old_pid) and old_pid != os.getpid():
                return  # already running
        except Exception:
            pass
        _PID_FILE.unlink(missing_ok=True)

    _PID_FILE.write_text(str(os.getpid()))

    try:
        app = NSApplication.sharedApplication()
        app.setActivationPolicy_(NSApplicationActivationPolicyAccessory)
        delegate = MenuBarDelegate.alloc().init()
        app.setDelegate_(delegate)
        AppHelper.runEventLoop()
    finally:
        _PID_FILE.unlink(missing_ok=True)


if __name__ == "__main__":
    run_menubar()
