"""
命令行工具
提供便捷的命令行接口
"""
import asyncio
import argparse
import sys
from pathlib import Path
from typing import Optional, List
from loguru import logger


class CLI:
    """命令行工具"""
    
    def __init__(self):
        self.parser = self._create_parser()
    
    def _create_parser(self) -> argparse.ArgumentParser:
        """创建参数解析器"""
        parser = argparse.ArgumentParser(
            description="Playwright-EZ - 简化的浏览器自动化工具",
            formatter_class=argparse.RawDescriptionHelpFormatter,
        )
        
        subparsers = parser.add_subparsers(dest="command", help="可用命令")
        
        # screenshot 命令
        screenshot_parser = subparsers.add_parser("screenshot", help="截取网页截图")
        screenshot_parser.add_argument("url", help="网页URL")
        screenshot_parser.add_argument("-o", "--output", default="screenshot.png", help="输出路径")
        screenshot_parser.add_argument("--full-page", action="store_true", help="全页面截图")
        screenshot_parser.add_argument("--wait", type=int, default=0, help="等待时间(秒)")
        
        # pdf 命令
        pdf_parser = subparsers.add_parser("pdf", help="保存网页为PDF")
        pdf_parser.add_argument("url", help="网页URL")
        pdf_parser.add_argument("-o", "--output", default="page.pdf", help="输出路径")
        
        # record 命令
        record_parser = subparsers.add_parser("record", help="录制操作")
        record_parser.add_argument("url", help="起始URL")
        record_parser.add_argument("-o", "--output", default="recording.json", help="输出路径")
        record_parser.add_argument("--headless", action="store_true", help="无头模式")
        
        # replay 命令
        replay_parser = subparsers.add_parser("replay", help="回放录制")
        replay_parser.add_argument("file", help="录制文件")
        replay_parser.add_argument("--speed", type=float, default=1.0, help="播放速度")
        
        # test 命令
        test_parser = subparsers.add_parser("test", help="运行测试")
        test_parser.add_argument("path", nargs="?", default="tests", help="测试路径")
        test_parser.add_argument("--headed", action="store_true", help="显示浏览器")
        test_parser.add_argument("--parallel", "-n", type=int, default=1, help="并行数")
        
        # scrape 命令
        scrape_parser = subparsers.add_parser("scrape", help="抓取网页数据")
        scrape_parser.add_argument("url", help="网页URL")
        scrape_parser.add_argument("-s", "--selector", help="选择器")
        scrape_parser.add_argument("-o", "--output", default="data.json", help="输出路径")
        scrape_parser.add_argument("--links", action="store_true", help="提取链接")
        scrape_parser.add_argument("--images", action="store_true", help="提取图片")
        scrape_parser.add_argument("--table", action="store_true", help="提取表格")
        
        # device 命令
        device_parser = subparsers.add_parser("devices", help="列出可用设备")
        
        # version 命令
        subparsers.add_parser("version", help="显示版本")
        
        return parser
    
    def run(self, args: List[str] = None):
        """运行命令"""
        parsed = self.parser.parse_args(args)
        
        if not parsed.command:
            self.parser.print_help()
            return
        
        # 路由到对应命令处理
        handler = getattr(self, f"cmd_{parsed.command}", None)
        if handler:
            asyncio.run(handler(parsed))
        else:
            print(f"未知命令: {parsed.command}")
    
    async def cmd_screenshot(self, args):
        """截图命令"""
        from .browser import EasyBrowser
        from .config import Config
        
        config = Config(headless=True)
        
        async with EasyBrowser(config) as browser:
            logger.info(f"访问: {args.url}")
            await browser.goto(args.url)
            
            if args.wait:
                await asyncio.sleep(args.wait)
            
            await browser.screenshot(args.output, full_page=args.full_page)
            logger.info(f"截图已保存: {args.output}")
    
    async def cmd_pdf(self, args):
        """PDF命令"""
        from .browser import EasyBrowser
        from .file_handler import FileHandler
        
        async with EasyBrowser() as browser:
            logger.info(f"访问: {args.url}")
            await browser.goto(args.url)
            
            file_handler = FileHandler(browser.page)
            await file_handler.pdf(args.output)
            logger.info(f"PDF已保存: {args.output}")
    
    async def cmd_record(self, args):
        """录制命令"""
        from .browser import EasyBrowser
        from .recorder import RecordingSession
        
        config = Config(headless=args.headless)
        
        async with EasyBrowser(config) as browser:
            session = RecordingSession(browser.page)
            
            logger.info(f"访问: {args.url}")
            await browser.goto(args.url)
            
            await session.start_recording()
            logger.info("开始录制... 按 Ctrl+C 停止")
            
            try:
                # 等待用户操作
                while True:
                    await asyncio.sleep(1)
            except KeyboardInterrupt:
                pass
            
            await session.stop_recording()
            session.save(args.output)
            
            # 导出Python代码
            py_output = args.output.replace(".json", ".py")
            session.export_python(py_output)
            
            logger.info(f"录制已保存: {args.output}")
            logger.info(f"代码已导出: {py_output}")
    
    async def cmd_replay(self, args):
        """回放命令"""
        from .browser import EasyBrowser
        from .recorder import RecordingSession
        
        async with EasyBrowser() as browser:
            session = RecordingSession(browser.page)
            session.load(args.file)
            
            logger.info(f"回放: {args.file}")
            await session.replay(speed=args.speed)
            
            logger.info("回放完成")
    
    async def cmd_test(self, args):
        """测试命令"""
        import subprocess
        
        cmd = ["pytest", args.path]
        
        if args.headed:
            cmd.append("--headed")
        
        if args.parallel > 1:
            cmd.extend(["-n", str(args.parallel)])
        
        subprocess.run(cmd)
    
    async def cmd_scrape(self, args):
        """抓取命令"""
        from .browser import EasyBrowser
        from .extract import DataExtractor, save_to_json
        
        async with EasyBrowser() as browser:
            logger.info(f"访问: {args.url}")
            await browser.goto(args.url)
            
            extractor = DataExtractor(browser.page)
            data = {}
            
            if args.selector:
                texts = await extractor.extract_texts(args.selector)
                data["texts"] = texts
            
            if args.links:
                data["links"] = await extractor.extract_links()
            
            if args.images:
                data["images"] = await extractor.extract_images()
            
            if args.table:
                data["table"] = await extractor.extract_table()
            
            if not data:
                # 默认提取meta信息
                data["meta"] = await extractor.extract_meta_tags()
                data["title"] = await browser.page.title()
            
            save_to_json(data, args.output)
            logger.info(f"数据已保存: {args.output}")
    
    async def cmd_devices(self, args):
        """设备列表命令"""
        from .mobile import DeviceEmulator
        
        emulator = DeviceEmulator()
        devices = emulator.list_devices()
        
        print("\n可用设备:")
        print("-" * 40)
        
        for name in sorted(devices):
            config = emulator.get_device(name)
            if config:
                print(f"  {name}")
                print(f"    尺寸: {config.viewport_width}x{config.viewport_height}")
                print(f"    移动端: {'是' if config.is_mobile else '否'}")
                print()
    
    async def cmd_version(self, args):
        """版本命令"""
        from . import __version__
        print(f"Playwright-EZ v{__version__}")


def main():
    """入口函数"""
    cli = CLI()
    cli.run()


if __name__ == "__main__":
    main()
