# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# ORCID: 0009-0006-4957-0540
# Email: Georgescottfoley@proton.me
# Licensed under the MIT License - see LICENSE file for details

"""
Video Search Skill

Agent-facing tools for searching, discovering, and inspecting videos.
Wraps the existing search helpers from ``_browse.py`` and ``yt-dlp``
so the agent can call them through the standard tool-calling loop.

Search backends:
  - Online: DuckDuckGo video search (multi-platform)
  - Local: ~/.familiar/video/index.json full-text match
  - Info:  yt-dlp --dump-json for single-URL metadata
"""

import json
import logging
import subprocess

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _format_duration(seconds):
    """Format seconds as H:MM:SS or M:SS."""
    if not seconds:
        return ""
    s = int(seconds)
    hrs, remainder = divmod(s, 3600)
    mins, secs = divmod(remainder, 60)
    if hrs:
        return f"{hrs}:{mins:02d}:{secs:02d}"
    return f"{mins}:{secs:02d}"


def _build_text_and_json(items, summary, query):
    """Build the dual-format return string: human text + JSON marker."""
    lines = [f"Found {len(items)} videos for: {query}\n"]
    for i, item in enumerate(items, 1):
        lines.append(f"  {i}. {item.get('name', '(untitled)')}")
        detail = item.get("detail", "")
        if detail:
            lines.append(f"     {detail}")
        url = item.get("url", "")
        if url:
            lines.append(f"     {url}")
        lines.append("")

    payload = {"items": items, "summary": summary}
    lines.append("SEARCH_RESULTS_JSON:")
    lines.append(json.dumps(payload))
    return "\n".join(lines)


# ---------------------------------------------------------------------------
# Tool handlers
# ---------------------------------------------------------------------------


def video_search(data: dict) -> str:
    """Search for videos online across YouTube, Vimeo, Dailymotion, etc."""
    from familiar.channels.connect_wizard._browse import search_video_online

    query = data.get("query", "").strip()
    if not query:
        return "Please provide a search query."

    max_results = min(int(data.get("max_results", 20)), 30)
    platform = data.get("platform", "all").strip().lower()

    # Modify query with site: prefix for platform-specific searches
    effective_query = query
    platform_sites = {
        "youtube": "youtube.com",
        "vimeo": "vimeo.com",
        "dailymotion": "dailymotion.com",
    }
    if platform in platform_sites:
        effective_query = f"{query} site:{platform_sites[platform]}"

    result = search_video_online(effective_query, max_results=max_results)
    items = result.get("items", [])
    summary = result.get("summary", f"{len(items)} results")

    if not items:
        if result.get("error"):
            return f"Video search failed: {result['error']}"
        return f"No video results found for: {query}"

    return _build_text_and_json(items, summary, query)


def video_search_local(data: dict) -> str:
    """Search the local video library (downloaded videos) by title, uploader, or description."""
    from familiar.channels.connect_wizard._browse import search_video

    query = data.get("query", "").strip()
    if not query:
        return "Please provide a search query."

    result = search_video(query)
    items = result.get("items", [])
    summary = result.get("summary", f"{len(items)} results")

    if not items:
        return f"No local videos found matching: {query}"

    return _build_text_and_json(items, summary, query)


def video_get_info(data: dict) -> str:
    """Get metadata for a specific video URL (title, duration, uploader, qualities)."""
    url = data.get("url", "").strip()
    if not url:
        return "Please provide a video URL."
    if not url.startswith(("http://", "https://")):
        url = "https://" + url

    try:
        result = subprocess.run(
            ["yt-dlp", "--dump-json", "--no-download", "--no-warnings", url],
            capture_output=True,
            text=True,
            timeout=30,
        )
        if result.returncode != 0:
            return f"Could not retrieve video info: {result.stderr.strip()[:200]}"

        info = json.loads(result.stdout.strip().split("\n")[0])

        title = info.get("title", "Unknown")
        duration = info.get("duration", 0)
        uploader = info.get("uploader", "Unknown")
        description = (info.get("description") or "")[:300]
        extractor = info.get("extractor", "unknown")

        # Collect available qualities
        qualities = set()
        for fmt in info.get("formats", []):
            res = fmt.get("resolution", "")
            if "x" in res or "p" in res:
                qualities.add(res)
        quality_list = sorted(qualities) if qualities else ["unknown"]

        lines = [
            f"Title: {title}",
            f"Duration: {_format_duration(duration)}",
            f"Uploader: {uploader}",
            f"Platform: {extractor}",
            f"Qualities: {', '.join(quality_list)}",
        ]
        if description:
            lines.append(f"Description: {description}")

        return "\n".join(lines)

    except subprocess.TimeoutExpired:
        return "Video info request timed out (30s). The URL may be slow or unreachable."
    except FileNotFoundError:
        return "yt-dlp is not installed. Install it with: pip install yt-dlp"
    except Exception as e:
        logger.warning(f"video_get_info failed for {url}: {e}")
        return f"Error retrieving video info: {e}"


# ---------------------------------------------------------------------------
# Tool definitions (auto-discovered by skill loader)
# ---------------------------------------------------------------------------

TOOLS = [
    {
        "name": "video_search",
        "description": (
            "Search for videos online across YouTube, Vimeo, Dailymotion, and other platforms. "
            "Use this when the user wants to find, watch, or discover videos on any topic. "
            "Returns a list of results with titles, uploaders, durations, and URLs."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Video search query",
                },
                "max_results": {
                    "type": "integer",
                    "default": 20,
                    "description": "Maximum results to return (up to 30)",
                },
                "platform": {
                    "type": "string",
                    "default": "all",
                    "description": (
                        "Filter by platform: 'all', 'youtube', 'vimeo', or 'dailymotion'"
                    ),
                },
            },
            "required": ["query"],
        },
        "handler": video_search,
        "category": "video",
    },
    {
        "name": "video_search_local",
        "description": (
            "Search the local video library (previously downloaded videos) by title, "
            "uploader, or description. Check this first before searching online."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Search query for local video library",
                },
            },
            "required": ["query"],
        },
        "handler": video_search_local,
        "category": "video",
    },
    {
        "name": "video_get_info",
        "description": (
            "Get detailed metadata for a specific video URL. Returns title, duration, "
            "uploader, description, and available quality options. Use this to inspect "
            "a video before recommending or downloading it."
        ),
        "input_schema": {
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "Full video URL to inspect",
                },
            },
            "required": ["url"],
        },
        "handler": video_get_info,
        "category": "video",
    },
]
