"""
Roneia Client - 权限确认 UI

提供权限确认的用户界面：
- Tkinter 弹窗（GUI 模式）
- 终端交互（CLI 模式）
"""

import asyncio
import logging
from typing import Dict, Any, List, Optional

logger = logging.getLogger(__name__)


class PermissionUI:
    """
    权限确认 UI

    支持 GUI 弹窗和终端两种模式。
    """

    def __init__(self, use_gui: bool = True, auto_grant: Optional[List[str]] = None):
        """
        初始化权限 UI

        Args:
            use_gui: 是否使用 GUI 弹窗
            auto_grant: 自动授权的权限列表
        """
        self._use_gui = use_gui
        self._auto_grant = set(auto_grant or [])

        # 检查 tkinter 是否可用
        if use_gui:
            try:
                import tkinter
                self._tkinter_available = True
            except ImportError:
                logger.warning("tkinter not available, falling back to terminal mode")
                self._tkinter_available = False
                self._use_gui = False

    def is_auto_granted(self, permission: str) -> bool:
        """
        检查权限是否自动授权

        Args:
            permission: 权限字符串

        Returns:
            是否自动授权
        """
        if permission in self._auto_grant:
            return True

        # 检查前缀匹配
        for auto_perm in self._auto_grant:
            if permission.startswith(auto_perm):
                return True

        return False

    async def request_permission(
        self,
        skill_name: str,
        permission: str,
        reason: str,
        purpose: str,
    ) -> bool:
        """
        请求用户授权

        Args:
            skill_name: Skill 名称
            permission: 权限字符串
            reason: 请求原因
            purpose: 操作目的

        Returns:
            是否授权
        """
        # 检查自动授权
        if self.is_auto_granted(permission):
            logger.info(f"Auto-granted permission: {permission}")
            return True

        # 使用 GUI 或终端
        if self._use_gui and self._tkinter_available:
            return await self._request_permission_gui(skill_name, permission, reason, purpose)
        else:
            return await self._request_permission_terminal(skill_name, permission, reason, purpose)

    async def _request_permission_gui(
        self,
        skill_name: str,
        permission: str,
        reason: str,
        purpose: str,
    ) -> bool:
        """使用 GUI 弹窗请求权限"""
        import tkinter as tk
        from tkinter import messagebox

        result = [None]

        def show_dialog():
            root = tk.Tk()
            root.withdraw()
            root.attributes('-topmost', True)

            message = f"""Skill: {skill_name}
操作: {purpose}

需要的权限:
  {permission}

原因: {reason}

是否授权？"""

            try:
                answer = messagebox.askyesno(
                    "权限授权请求",
                    message,
                    parent=root
                )
                result[0] = answer
            except Exception as e:
                logger.error(f"Permission dialog error: {e}")
                result[0] = False
            finally:
                try:
                    root.destroy()
                except Exception:
                    pass

        # 在主线程中运行 tkinter
        loop = asyncio.get_event_loop()
        await loop.run_in_executor(None, show_dialog)

        return result[0] == True

    async def _request_permission_terminal(
        self,
        skill_name: str,
        permission: str,
        reason: str,
        purpose: str,
    ) -> bool:
        """使用终端请求权限"""
        print()
        print("=" * 50)
        print("        权限授权请求")
        print("=" * 50)
        print(f"Skill: {skill_name}")
        print(f"操作: {purpose}")
        print()
        print("需要的权限:")
        print(f"  {permission}")
        print()
        if reason:
            print(f"原因: {reason}")
        print("-" * 50)
        print("输入 y 授权，n 拒绝:")

        try:
            # 使用 asyncio 的方式等待输入
            loop = asyncio.get_event_loop()
            user_input = await loop.run_in_executor(
                None,
                lambda: input("> ").strip().lower()
            )
            return user_input in ("y", "yes", "是", "授权")
        except (EOFError, KeyboardInterrupt):
            return False


class PermissionManager:
    """
    本地权限管理器

    管理客户端的权限授权。
    """

    def __init__(self, ui: PermissionUI):
        """
        初始化权限管理器

        Args:
            ui: 权限 UI 实例
        """
        self._ui = ui

        # 会话内的临时授权缓存
        self._session_grants: Dict[str, bool] = {}

    async def check_and_request(
        self,
        skill_name: str,
        permission: str,
        reason: str = "",
        purpose: str = "",
    ) -> bool:
        """
        检查并请求权限

        Args:
            skill_name: Skill 名称
            permission: 权限字符串
            reason: 请求原因
            purpose: 操作目的

        Returns:
            是否有权限
        """
        cache_key = f"{skill_name}:{permission}"

        # 检查会话缓存
        if cache_key in self._session_grants:
            return self._session_grants[cache_key]

        # 请求用户授权
        granted = await self._ui.request_permission(
            skill_name, permission, reason, purpose
        )

        # 缓存结果（仅在会话内有效）
        self._session_grants[cache_key] = granted

        return granted

    def clear_session_cache(self) -> None:
        """清除会话缓存"""
        self._session_grants.clear()

    def revoke(self, skill_name: str, permission: str) -> None:
        """撤销权限"""
        cache_key = f"{skill_name}:{permission}"
        self._session_grants.pop(cache_key, None)


async def show_notification(title: str, message: str) -> None:
    """
    显示通知

    Args:
        title: 通知标题
        message: 通知内容
    """
    try:
        import tkinter as tk
        from tkinter import messagebox

        def show():
            root = tk.Tk()
            root.withdraw()
            root.attributes('-topmost', True)
            messagebox.showinfo(title, message, parent=root)
            root.destroy()

        loop = asyncio.get_event_loop()
        await loop.run_in_executor(None, show)

    except ImportError:
        # 如果没有 tkinter，打印到终端
        print(f"\n[{title}] {message}\n")
