"""Recording and playback functionality."""

import json
from datetime import datetime
from pathlib import Path
from typing import Any, Optional

from .browser import Browser


class ActionRecorder:
    """
    Record browser actions for later playback.
    
    Usage:
        recorder = ActionRecorder()
        
        # Start recording
        recorder.start()
        
        # Perform actions
        await browser.goto('example.com')
        await browser.click('button')
        
        # Record the actions
        recorder.record('goto', {'url': 'example.com'})
        recorder.record('click', {'selector': 'button'})
        
        # Stop and save
        recorder.stop()
        recorder.save('/mnt/fnos/SurfAI/项目文件/导出数据/recording.json')
        
        # Playback later
        player = ActionPlayer()
        await player.play('/mnt/fnos/SurfAI/项目文件/导出数据/recording.json', browser)
    """
    
    def __init__(self):
        self._recording: list[dict] = []
        self._is_recording = False
        self._start_time: Optional[datetime] = None
    
    def start(self) -> None:
        """Start recording."""
        self._recording = []
        self._is_recording = True
        self._start_time = datetime.now()
        print("🔴 开始录制...")
    
    def stop(self) -> None:
        """Stop recording."""
        self._is_recording = False
        duration = (datetime.now() - self._start_time).total_seconds() if self._start_time else 0
        print(f"⏹️  录制结束，共 {len(self._recording)} 个动作，耗时 {duration:.1f} 秒")
    
    def record(self, action_type: str, params: dict, timestamp: Optional[float] = None) -> None:
        """
        Record an action.
        
        Args:
            action_type: Type of action (goto, click, type, etc.)
            params: Action parameters
            timestamp: Time since start (optional)
        """
        if not self._is_recording:
            return
        
        if timestamp is None and self._start_time:
            timestamp = (datetime.now() - self._start_time).total_seconds()
        
        self._recording.append({
            "type": action_type,
            "params": params,
            "timestamp": timestamp or 0,
        })
        
        print(f"   📝 录制: {action_type} {params}")
    
    def save(self, filepath: Optional[str] = None) -> str:
        """
        Save recording to file.
        
        Args:
            filepath: Output file path (default: project folder)
            
        Returns:
            Path to saved file
        """
        if filepath is None:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filepath = f"/mnt/fnos/SurfAI/项目文件/导出数据/recording_{timestamp}.json"
        
        path = Path(filepath)
        path.parent.mkdir(parents=True, exist_ok=True)
        
        data = {
            "version": "1.0",
            "created_at": datetime.now().isoformat(),
            "action_count": len(self._recording),
            "actions": self._recording,
        }
        
        with open(path, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        
        print(f"💾 录制已保存: {path}")
        return str(path)
    
    def get_recording(self) -> list[dict]:
        """Get the recorded actions."""
        return self._recording.copy()
    
    def clear(self) -> None:
        """Clear the recording."""
        self._recording = []
        print("🗑️  录制已清空")


class ActionPlayer:
    """
    Playback recorded actions.
    
    Usage:
        player = ActionPlayer()
        await player.play('recording.json', browser)
    """
    
    async def play(
        self,
        recording_path: str,
        browser: Browser,
        delay: float = 1.0,
        on_action: Optional[callable] = None,
    ) -> None:
        """
        Play back a recording.
        
        Args:
            recording_path: Path to recording file
            browser: Browser instance
            delay: Delay between actions (seconds)
            on_action: Callback for each action
        """
        # Load recording
        with open(recording_path, "r", encoding="utf-8") as f:
            data = json.load(f)
        
        actions = data.get("actions", [])
        print(f"▶️  开始回放，共 {len(actions)} 个动作")
        print("-" * 60)
        
        for i, action in enumerate(actions, 1):
            action_type = action.get("type")
            params = action.get("params", {})
            
            print(f"   [{i}/{len(actions)}] 执行: {action_type}")
            
            try:
                if action_type == "goto":
                    await browser.goto(params.get("url", ""))
                
                elif action_type == "click":
                    await browser.click(params.get("selector", ""))
                
                elif action_type == "type":
                    await browser.type(
                        params.get("selector", ""),
                        params.get("text", "")
                    )
                
                elif action_type == "extract":
                    result = await browser.extract(params.get("selector", ""))
                    print(f"      提取结果: {result[:50]}...")
                
                elif action_type == "screenshot":
                    result = await browser.screenshot()
                    print(f"      截图: {result['path']}")
                
                elif action_type == "wait":
                    import asyncio
                    await asyncio.sleep(params.get("seconds", 1))
                
                elif action_type == "scroll":
                    await browser.scroll(
                        params.get("direction", "down"),
                        params.get("amount", 500)
                    )
                
                else:
                    print(f"      ⚠️  未知动作类型: {action_type}")
                
                if on_action:
                    on_action(action_type, params, True)
                
            except Exception as e:
                print(f"      ❌ 执行失败: {e}")
                if on_action:
                    on_action(action_type, params, False)
            
            # Delay between actions
            if delay > 0 and i < len(actions):
                import asyncio
                await asyncio.sleep(delay)
        
        print("-" * 60)
        print("✅ 回放完成")
    
    def validate(self, recording_path: str) -> bool:
        """
        Validate a recording file.
        
        Args:
            recording_path: Path to recording file
            
        Returns:
            True if valid, False otherwise
        """
        try:
            with open(recording_path, "r", encoding="utf-8") as f:
                data = json.load(f)
            
            # Check required fields
            if "actions" not in data:
                print("❌ 无效的录制文件: 缺少 actions 字段")
                return False
            
            actions = data.get("actions", [])
            for i, action in enumerate(actions):
                if "type" not in action:
                    print(f"❌ 动作 #{i} 缺少 type 字段")
                    return False
            
            print(f"✅ 录制文件有效，共 {len(actions)} 个动作")
            return True
            
        except json.JSONDecodeError:
            print("❌ 无效的 JSON 文件")
            return False
        except Exception as e:
            print(f"❌ 验证失败: {e}")
            return False


class RecordingBrowser(Browser):
    """
    Browser with built-in recording capability.
    
    Usage:
        browser = RecordingBrowser()
        recorder = browser.start_recording()
        
        # Perform actions
        await browser.goto('example.com')
        await browser.click('button')
        
        # Stop and save
        browser.stop_recording()
        browser.save_recording()
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._recorder: Optional[ActionRecorder] = None
    
    def start_recording(self) -> ActionRecorder:
        """Start recording actions."""
        self._recorder = ActionRecorder()
        self._recorder.start()
        return self._recorder
    
    def stop_recording(self) -> None:
        """Stop recording actions."""
        if self._recorder:
            self._recorder.stop()
    
    def save_recording(self, filepath: Optional[str] = None) -> str:
        """Save the recording."""
        if not self._recorder:
            raise RuntimeError("No recording in progress")
        return self._recorder.save(filepath)
    
    async def goto(self, url: str, wait_until: str = "networkidle") -> "Browser":
        """Navigate to URL and record."""
        if self._recorder and self._recorder._is_recording:
            self._recorder.record("goto", {"url": url})
        return await super().goto(url, wait_until)
    
    async def click(self, selector: str) -> "Browser":
        """Click element and record."""
        if self._recorder and self._recorder._is_recording:
            self._recorder.record("click", {"selector": selector})
        return await super().click(selector)
    
    async def type(self, selector: str, text: str) -> "Browser":
        """Type text and record."""
        if self._recorder and self._recorder._is_recording:
            self._recorder.record("type", {"selector": selector, "text": text})
        return await super().type(selector, text)
