"""
应用管理技能 - 打开、关闭、切换应用
"""

import re
import logging
import sys
import os
from typing import Dict, Any, List

# 兼容独立运行和包导入
_agent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if _agent_dir not in sys.path:
    sys.path.insert(0, _agent_dir)

try:
    from skills.base import BaseSkill
except ImportError:
    from ..base import BaseSkill

logger = logging.getLogger(__name__)


class AppManagerSkill(BaseSkill):
    """应用管理技能"""
    
    PACKAGE = ""  # 通用技能
    NAME = "应用管理"
    
    # 常用应用包名
    APP_PACKAGES = {
        "微信": "com.tencent.mm",
        "抖音": "com.ss.android.ugc.aweme",
        "支付宝": "com.eg.android.AlipayGphone",
        "淘宝": "com.taobao.taobao",
        "微博": "com.sina.weibo",
        "qq": "com.tencent.mobileqq",
        "设置": "com.android.settings",
        "相机": "com.android.camera",
        "浏览器": "com.android.chrome",
        "豆包": "com.bytedance.doubao",
        "小红书": "com.xingin.xhs",
        "bilibili": "tv.danmaku.bili",
        "知乎": "com.zhihu.android",
    }
    
    def open_app(self, app_name: str) -> Dict[str, Any]:
        """
        打开应用
        
        Args:
            app_name: 应用名称（中文或包名）
            
        Returns:
            执行结果
        """
        try:
            # 查找包名
            package = self.APP_PACKAGES.get(app_name)
            if not package:
                # 尝试直接作为包名
                package = app_name
            
            # 启动应用
            self.d.app_start(package)
            self.sleep(2)
            
            # 验证是否启动成功
            current = self.d.app_current()
            if current.get("package") == package:
                return {
                    "success": True,
                    "app_name": app_name,
                    "package": package,
                    "message": f"已打开{app_name}"
                }
            else:
                return {
                    "success": False,
                    "error": f"应用启动失败或包名错误: {app_name}",
                    "package": package
                }
                
        except Exception as e:
            logger.error(f"打开应用失败 {app_name}: {e}")
            return {
                "success": False,
                "error": str(e),
                "app_name": app_name
            }
    
    def close_app(self, app_name: str = None, package: str = None) -> Dict[str, Any]:
        """
        关闭应用
        
        Args:
            app_name: 应用名称
            package: 包名（优先）
            
        Returns:
            执行结果
        """
        try:
            if package:
                target_package = package
            elif app_name:
                target_package = self.APP_PACKAGES.get(app_name, app_name)
            else:
                # 关闭当前应用
                current = self.d.app_current()
                target_package = current.get("package")
            
            if target_package:
                self.d.app_stop(target_package)
                return {
                    "success": True,
                    "package": target_package,
                    "message": "应用已关闭"
                }
            else:
                return {"success": False, "error": "未指定应用"}
                
        except Exception as e:
            logger.error(f"关闭应用失败: {e}")
            return {"success": False, "error": str(e)}
    
    def get_running_apps(self) -> Dict[str, Any]:
        """获取正在运行的应用列表"""
        try:
            self.d.press("recent")
            self.sleep(1)
            ui_tree = self.d.dump_hierarchy()
            apps = self._parse_recent_tasks_from_ui(ui_tree)
            self.home()
            return {"success": True, "apps": apps}
        except Exception as e:
            return {"success": False, "error": str(e), "apps": []}

    @staticmethod
    def _parse_recent_tasks_from_ui(xml: str) -> List[Dict[str, Any]]:
        """从最近任务 UI 解析应用标题占位"""
        out = []
        if not xml:
            return out
        skip = {"最近", "清除", "关闭", "全部", "清理"}
        for i, m in enumerate(re.finditer(r'\b(text|content-desc)="([^"]{1,80})"', xml)):
            if i >= 50:
                break
            text = m.group(2).strip()
            if text and text not in skip and not text.startswith("com."):
                out.append({"index": len(out) + 1, "title": text})
        return out
    
    def get_installed_apps(self, limit: int = 100) -> Dict[str, Any]:
        """获取已安装的应用列表"""
        try:
            # 通过shell命令获取
            result = self.d.shell("pm list packages -3")  # 第三方应用
            packages = []
            
            for line in result.output.split('\n'):
                if line.startswith('package:'):
                    pkg = line.replace('package:', '').strip()
                    packages.append(pkg)
            
            return {
                "success": True,
                "packages": packages[:limit],
                "total": len(packages)
            }
            
        except Exception as e:
            return {"success": False, "error": str(e), "packages": []}
    
    def switch_app(self, app_name: str) -> Dict[str, Any]:
        """
        切换应用（如果已打开则切换，否则打开）
        
        Args:
            app_name: 应用名称
            
        Returns:
            执行结果
        """
        try:
            package = self.APP_PACKAGES.get(app_name, app_name)
            
            # 检查是否正在运行
            current = self.d.app_current()
            if current.get("package") == package:
                return {
                    "success": True,
                    "message": f"{app_name}已是当前应用",
                    "package": package
                }
            
            # 打开或切换
            self.d.app_start(package)
            self.sleep(2)
            
            return {
                "success": True,
                "app_name": app_name,
                "package": package,
                "message": f"已切换到{app_name}"
            }
            
        except Exception as e:
            logger.error(f"切换应用失败 {app_name}: {e}")
            return {
                "success": False,
                "error": str(e),
                "app_name": app_name
            }
