"""macOS activation dialog for MuraveyChina license system.

Uses native NSPanel for token entry. Does NOT depend on rumps.
Falls back to a simple input dialog if AppKit is unavailable.
"""

from __future__ import annotations

import logging
import sys
import webbrowser

PURCHASE_PAGE_URL = "https://whop.com/checkout/plan_YFqvqKJproMsR"

log = logging.getLogger(__name__)

_NSTitledWindowMask = 1 << 0
_NSClosableWindowMask = 1 << 1
_NSCommandKeyMask = 1 << 20  # NSEventModifierFlagCommand


def _has_appkit() -> bool:
    try:
        import AppKit  # noqa: F401

        return True
    except ImportError:
        return False


class ActivationDialog:
    """Modal activation dialog for macOS using native AppKit."""

    def __init__(self, license_manager) -> None:
        self._mgr = license_manager

    def show_and_activate(self) -> bool:
        """Show activation dialog. Returns True if activation succeeded."""
        if not _has_appkit():
            log.warning("AppKit unavailable — skipping activation dialog")
            return False

        try:
            return self._run_native()
        except Exception:
            log.exception("Native activation dialog failed")
            return False

    def _run_native(self) -> bool:
        import AppKit
        import objc

        class _PasteTextField(AppKit.NSTextField):
            def performKeyEquivalent_(self, event):
                if (
                    event.modifierFlags() & _NSCommandKeyMask
                    and event.charactersIgnoringModifiers() == "v"
                ):
                    self.paste_(None)
                    return True
                return objc.super(_PasteTextField, self).performKeyEquivalent_(event)

        class _TokenPanelDelegate(AppKit.NSObject):
            def activateClicked_(self, sender):
                self._result[0] = 1
                AppKit.NSApp.stopModal()

            def cancelClicked_(self, sender):
                self._result[0] = 0
                AppKit.NSApp.stopModal()

            def buyClicked_(self, sender):
                webbrowser.open(PURCHASE_PAGE_URL)

            def windowWillClose_(self, notification):
                AppKit.NSApp.stopModal()

            def windowDidBecomeKey_(self, notification):
                panel = getattr(self, "_panel", None)
                field = getattr(self, "_field", None)
                if panel and field:
                    AppKit.NSApp.activateIgnoringOtherApps_(True)
                    panel.makeFirstResponder_(field)

        while True:
            try:
                AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyRegular)
                AppKit.NSApp.activateIgnoringOtherApps_(True)
            except AttributeError:
                pass

            WIDTH, HEIGHT = 460, 260
            frame = AppKit.NSMakeRect(0, 0, WIDTH, HEIGHT)

            panel = AppKit.NSPanel.alloc().initWithContentRect_styleMask_backing_defer_(
                frame,
                _NSTitledWindowMask | _NSClosableWindowMask,
                AppKit.NSBackingStoreBuffered,
                False,
            )
            panel.setTitle_("MuraveyChina — Activation")
            panel.setLevel_(AppKit.NSFloatingWindowLevel)
            panel.setHidesOnDeactivate_(False)
            panel.setReleasedWhenClosed_(False)

            result = [0]
            content = panel.contentView()
            p = 20

            lbl = AppKit.NSTextField.labelWithString_(
                "A license is required to use MuraveyChina.\n"
                "Enter the activation token you received via Telegram.\n"
                "The license is bound to this device."
            )
            lbl.setFrame_(AppKit.NSMakeRect(p, HEIGHT - 100, WIDTH - 2 * p, 80))
            lbl.cell().setWraps_(True)
            lbl.setSelectable_(False)
            content.addSubview_(lbl)

            field = _PasteTextField.alloc().initWithFrame_(
                AppKit.NSMakeRect(p, HEIGHT - 140, WIDTH - 2 * p, 32)
            )
            field.setPlaceholderString_("Paste activation token (Cmd+V)")
            field.setEditable_(True)
            field.setSelectable_(True)
            field.setBezeled_(True)
            field.setDrawsBackground_(True)
            content.addSubview_(field)

            # Status label
            status_lbl = AppKit.NSTextField.labelWithString_("")
            status_lbl.setFrame_(AppKit.NSMakeRect(p, HEIGHT - 170, WIDTH - 2 * p, 20))
            status_lbl.setSelectable_(False)
            content.addSubview_(status_lbl)

            delegate = _TokenPanelDelegate.alloc().init()
            delegate._result = result
            delegate._panel = panel
            delegate._field = field
            panel.setDelegate_(delegate)

            # Buy button
            buy_btn = AppKit.NSButton.alloc().initWithFrame_(AppKit.NSMakeRect(p, p, 80, 32))
            buy_btn.setTitle_("Buy")
            buy_btn.setBezelStyle_(AppKit.NSBezelStyleRounded)
            buy_btn.setTarget_(delegate)
            buy_btn.setAction_(objc.selector(delegate.buyClicked_, signature=b"v@:@"))
            content.addSubview_(buy_btn)

            # Cancel button
            cancel_btn = AppKit.NSButton.alloc().initWithFrame_(
                AppKit.NSMakeRect(WIDTH - p - 240, p, 100, 32)
            )
            cancel_btn.setTitle_("Exit")
            cancel_btn.setBezelStyle_(AppKit.NSBezelStyleRounded)
            cancel_btn.setTarget_(delegate)
            cancel_btn.setAction_(objc.selector(delegate.cancelClicked_, signature=b"v@:@"))
            cancel_btn.setKeyEquivalent_("\033")
            content.addSubview_(cancel_btn)

            # Activate button
            ok_btn = AppKit.NSButton.alloc().initWithFrame_(
                AppKit.NSMakeRect(WIDTH - p - 130, p, 130, 32)
            )
            ok_btn.setTitle_("Activate")
            ok_btn.setBezelStyle_(AppKit.NSBezelStyleRounded)
            ok_btn.setTarget_(delegate)
            ok_btn.setAction_(objc.selector(delegate.activateClicked_, signature=b"v@:@"))
            ok_btn.setKeyEquivalent_("\r")
            content.addSubview_(ok_btn)

            panel.setInitialFirstResponder_(field)
            panel.center()
            panel.makeKeyAndOrderFront_(None)
            panel.makeFirstResponder_(field)
            AppKit.NSApp.runModalForWindow_(panel)
            panel.orderOut_(None)

            try:
                AppKit.NSApp.activateIgnoringOtherApps_(True)
            except AttributeError:
                pass

            if result[0] == 0:
                # Restore accessory policy
                try:
                    AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyAccessory)
                except AttributeError:
                    pass
                return False

            # Attempt activation
            token = field.stringValue().strip()
            if not token:
                continue

            log.info("Attempting activation with token %s...", token[:8])
            activation = self._mgr.activate(token)

            if activation.success:
                hours = activation.time_remaining // 3600
                log.info("Activation successful. Session valid for %dh", hours)
                try:
                    AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyAccessory)
                except AttributeError:
                    pass
                return True

            # Show error and retry
            alert = AppKit.NSAlert.alloc().init()
            alert.setMessageText_("Activation Failed")
            alert.setInformativeText_(f"{activation.error}\n\nRetry?")
            alert.addButtonWithTitle_("Retry")
            alert.addButtonWithTitle_("Exit")
            response = alert.runModal()
            if response != 1000:  # Not "Retry"
                try:
                    AppKit.NSApp.setActivationPolicy_(AppKit.NSApplicationActivationPolicyAccessory)
                except AttributeError:
                    pass
                return False

    def show_expiry_warning(self, minutes_remaining: int) -> None:
        """Show macOS notification when session is about to expire."""
        try:
            import AppKit
            import Foundation

            notification = Foundation.NSUserNotification.alloc().init()
            notification.setTitle_("MuraveyChina")
            notification.setInformativeText_(f"License expires in {minutes_remaining} minutes. Please renew.")
            center = Foundation.NSUserNotificationCenter.defaultUserNotificationCenter()
            center.deliverNotification_(notification)
        except Exception:
            log.warning("Session expires in %d minutes", minutes_remaining)

    def show_expired_dialog(self) -> None:
        """Show dialog when session has expired."""
        if not _has_appkit():
            return
        try:
            import AppKit

            alert = AppKit.NSAlert.alloc().init()
            alert.setMessageText_("MuraveyChina — License Expired")
            alert.setInformativeText_("Your license has expired.\nPurchase a new license to continue.")
            alert.addButtonWithTitle_("Buy license")
            alert.addButtonWithTitle_("Exit")
            response = alert.runModal()
            if response == 1000:
                webbrowser.open(PURCHASE_PAGE_URL)
        except Exception:
            log.exception("show_expired_dialog failed")
        sys.exit(0)
