#!/usr/bin/env python3
"""
YouTube Insight Dispatcher
==========================
RWL-based dispatcher that processes YouTube Scout insights and implements them.

This dispatcher:
1. Reads insight tasks from youtube_insight_tasks.json
2. Prioritizes based on impact and relevance
3. Executes implementation through RWL loops
4. Tracks progress and reports results

Runs as part of the 8pm-4am nightly cycle.
"""

import json
import asyncio
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional
import hashlib


class YouTubeInsightDispatcher:
    """Dispatches YouTube insight tasks to RWL execution."""

    def __init__(self):
        self.base_path = Path("/mnt/e/genesis-system")
        self.tasks_file = self.base_path / "loop" / "youtube_insight_tasks.json"
        self.rwl_queue = self.base_path / "loop" / "rwl_queue.json"
        self.progress_file = self.base_path / "loop" / "youtube_dispatch_progress.json"
        self.log_file = self.base_path / "logs" / "youtube_dispatcher.log"

    def _log(self, message: str):
        """Log dispatcher activity."""
        timestamp = datetime.now().isoformat()
        log_entry = f"[{timestamp}] {message}"
        print(log_entry)

        self.log_file.parent.mkdir(parents=True, exist_ok=True)
        with open(self.log_file, "a") as f:
            f.write(log_entry + "\n")

    def _load_tasks(self) -> Dict[str, Any]:
        """Load insight tasks from file."""
        if not self.tasks_file.exists():
            return {"tasks": [], "metadata": {}}

        with open(self.tasks_file) as f:
            return json.load(f)

    def _save_tasks(self, data: Dict[str, Any]):
        """Save updated tasks back to file."""
        data["updated_at"] = datetime.now().isoformat()
        with open(self.tasks_file, "w") as f:
            json.dump(data, f, indent=2)

    def _load_rwl_queue(self) -> List[Dict]:
        """Load current RWL queue."""
        if not self.rwl_queue.exists():
            return []

        with open(self.rwl_queue) as f:
            data = json.load(f)
            return data.get("queue", [])

    def _save_rwl_queue(self, queue: List[Dict]):
        """Save RWL queue."""
        with open(self.rwl_queue, "w") as f:
            json.dump({
                "queue": queue,
                "updated": datetime.now().isoformat()
            }, f, indent=2)

    def get_pending_tasks(self) -> List[Dict]:
        """Get all pending insight tasks, sorted by priority."""
        data = self._load_tasks()
        tasks = data.get("tasks", [])

        # Filter pending tasks
        pending = [t for t in tasks if t.get("status") == "pending"]

        # Sort by priority (critical > high > medium > low)
        priority_order = {"critical": 0, "high": 1, "medium": 2, "low": 3}
        pending.sort(key=lambda t: priority_order.get(t.get("priority", "medium"), 2))

        return pending

    def dispatch_task(self, task: Dict) -> bool:
        """
        Dispatch a single task to RWL queue for execution.

        Returns True if successfully dispatched.
        """
        task_id = task.get("id", "unknown")
        self._log(f"Dispatching task: {task_id} - {task.get('title', 'No title')}")

        # Create RWL-formatted task
        rwl_task = {
            "id": f"yt_{task_id}",
            "title": task.get("title", "YouTube Insight Implementation"),
            "description": self._format_rwl_description(task),
            "source": "youtube_scout",
            "source_video": task.get("source_video", {}),
            "priority": task.get("priority", "medium"),
            "created_at": datetime.now().isoformat(),
            "insight_type": task.get("insight_type", "technique"),
            "tags": task.get("tags", []),
            "status": "queued"
        }

        # Add to RWL queue
        queue = self._load_rwl_queue()

        # Check for duplicates
        existing_ids = {t.get("id") for t in queue}
        if rwl_task["id"] in existing_ids:
            self._log(f"Task {task_id} already in queue, skipping")
            return False

        queue.append(rwl_task)
        self._save_rwl_queue(queue)

        # Update task status
        self._update_task_status(task_id, "dispatched")

        self._log(f"Task {task_id} dispatched successfully")
        return True

    def _format_rwl_description(self, task: Dict) -> str:
        """Format task description for RWL execution."""
        parts = []

        # Main description
        parts.append(task.get("description", "Implement YouTube insight"))

        # Add context
        if task.get("insight_type"):
            parts.append(f"\nInsight Type: {task['insight_type']}")

        if task.get("source_video"):
            video = task["source_video"]
            parts.append(f"\nSource: {video.get('title', 'Unknown')} by {video.get('channel', 'Unknown')}")
            if video.get("url"):
                parts.append(f"URL: {video['url']}")

        # Add implementation hints based on insight type
        insight_type = task.get("insight_type", "technique")
        if insight_type == "tool":
            parts.append("\n\nImplementation Steps:")
            parts.append("1. Research the tool/library mentioned")
            parts.append("2. Evaluate fit for Genesis architecture")
            parts.append("3. Create proof-of-concept integration")
            parts.append("4. Document in KNOWLEDGE_GRAPH if valuable")

        elif insight_type == "technique":
            parts.append("\n\nImplementation Steps:")
            parts.append("1. Understand the technique deeply")
            parts.append("2. Identify where it applies in Genesis")
            parts.append("3. Implement in relevant module(s)")
            parts.append("4. Add to skills if reusable")

        elif insight_type == "integration":
            parts.append("\n\nImplementation Steps:")
            parts.append("1. Map integration points")
            parts.append("2. Create bridge/adapter if needed")
            parts.append("3. Test connectivity and data flow")
            parts.append("4. Add to integration map")

        elif insight_type == "architecture":
            parts.append("\n\nImplementation Steps:")
            parts.append("1. Document architecture pattern")
            parts.append("2. Assess current Genesis alignment")
            parts.append("3. Create migration plan if beneficial")
            parts.append("4. Implement incrementally")

        return "\n".join(parts)

    def _update_task_status(self, task_id: str, status: str):
        """Update status of a specific task."""
        data = self._load_tasks()
        tasks = data.get("tasks", [])

        for task in tasks:
            if task.get("id") == task_id:
                task["status"] = status
                task["updated_at"] = datetime.now().isoformat()
                break

        self._save_tasks(data)

    def dispatch_batch(self, max_tasks: int = 5) -> Dict[str, Any]:
        """
        Dispatch a batch of high-priority tasks.

        Args:
            max_tasks: Maximum tasks to dispatch in this batch

        Returns:
            Summary of dispatch results
        """
        self._log(f"Starting batch dispatch (max: {max_tasks})")

        pending = self.get_pending_tasks()
        self._log(f"Found {len(pending)} pending tasks")

        dispatched = 0
        skipped = 0

        for task in pending[:max_tasks]:
            if self.dispatch_task(task):
                dispatched += 1
            else:
                skipped += 1

        result = {
            "dispatched": dispatched,
            "skipped": skipped,
            "remaining": len(pending) - dispatched,
            "timestamp": datetime.now().isoformat()
        }

        self._log(f"Batch complete: {dispatched} dispatched, {skipped} skipped")
        return result

    def get_dispatch_stats(self) -> Dict[str, Any]:
        """Get statistics about dispatch activity."""
        data = self._load_tasks()
        tasks = data.get("tasks", [])

        stats = {
            "total_tasks": len(tasks),
            "by_status": {},
            "by_priority": {},
            "by_type": {}
        }

        for task in tasks:
            # Count by status
            status = task.get("status", "unknown")
            stats["by_status"][status] = stats["by_status"].get(status, 0) + 1

            # Count by priority
            priority = task.get("priority", "medium")
            stats["by_priority"][priority] = stats["by_priority"].get(priority, 0) + 1

            # Count by type
            itype = task.get("insight_type", "unknown")
            stats["by_type"][itype] = stats["by_type"].get(itype, 0) + 1

        return stats

    def mark_completed(self, task_id: str, result: Dict = None):
        """Mark a task as completed with optional result data."""
        data = self._load_tasks()
        tasks = data.get("tasks", [])

        for task in tasks:
            if task.get("id") == task_id:
                task["status"] = "completed"
                task["completed_at"] = datetime.now().isoformat()
                if result:
                    task["result"] = result
                break

        self._save_tasks(data)
        self._log(f"Task {task_id} marked completed")

    def generate_nightly_report(self) -> str:
        """Generate a report of nightly dispatch activity."""
        stats = self.get_dispatch_stats()

        report = []
        report.append("=" * 50)
        report.append("YOUTUBE INSIGHT DISPATCHER - NIGHTLY REPORT")
        report.append(f"Generated: {datetime.now().isoformat()}")
        report.append("=" * 50)

        report.append(f"\nTotal Tasks: {stats['total_tasks']}")

        report.append("\nBy Status:")
        for status, count in stats["by_status"].items():
            report.append(f"  {status}: {count}")

        report.append("\nBy Priority:")
        for priority, count in stats["by_priority"].items():
            report.append(f"  {priority}: {count}")

        report.append("\nBy Insight Type:")
        for itype, count in stats["by_type"].items():
            report.append(f"  {itype}: {count}")

        # RWL queue status
        queue = self._load_rwl_queue()
        yt_tasks = [t for t in queue if t.get("source") == "youtube_scout"]
        report.append(f"\nRWL Queue (YouTube): {len(yt_tasks)} tasks")

        report.append("\n" + "=" * 50)

        return "\n".join(report)


def run_nightly_dispatch(max_tasks: int = 10) -> Dict[str, Any]:
    """
    Main entry point for nightly dispatch run.

    Called by n8n workflow during 8pm-4am window.
    """
    dispatcher = YouTubeInsightDispatcher()

    print("\n[YouTube Insight Dispatcher - Nightly Run]")
    print(f"Time: {datetime.now().isoformat()}")

    # Dispatch batch
    result = dispatcher.dispatch_batch(max_tasks)

    # Generate report
    report = dispatcher.generate_nightly_report()
    print(report)

    return {
        "dispatch_result": result,
        "stats": dispatcher.get_dispatch_stats()
    }


if __name__ == "__main__":
    import sys

    max_tasks = int(sys.argv[1]) if len(sys.argv) > 1 else 5
    result = run_nightly_dispatch(max_tasks)
    print(json.dumps(result, indent=2, default=str))
