"""MPV Lua API - Clean interface for Lua scripts to call Python functions.

This module provides a streamlined way for mpv Lua scripts to execute Python
functions and commands without relying on the broken observe_property IPC pattern.

Instead, Lua calls Python CLI directly via subprocess, and Python returns JSON
responses that Lua can parse.
"""

import json
import logging
import sys
from pathlib import Path
from typing import Any, Dict, Optional

# Add parent directory to path so we can import CLI, pipeline, cmdlet_catalog from root
_SCRIPT_DIR = Path(__file__).parent
_ROOT_DIR = _SCRIPT_DIR.parent
if str(_ROOT_DIR) not in sys.path:
    sys.path.insert(0, str(_ROOT_DIR))


def setup_logging(log_file: Optional[Path] = None) -> logging.Logger:
    """Setup logging for MPV API calls."""
    logger = logging.getLogger("mpv-lua-api")
    logger.setLevel(logging.DEBUG)

    if not logger.handlers:
        if log_file:
            handler = logging.FileHandler(str(log_file), encoding="utf-8")
        else:
            handler = logging.StreamHandler(sys.stderr)

        formatter = logging.Formatter(
            "[%(asctime)s][%(levelname)s] %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S"
        )
        handler.setFormatter(formatter)
        logger.addHandler(handler)

    return logger


def log_to_helper(msg: str, log_file: Optional[Path] = None) -> None:
    """Log a message that will appear in the helper log."""
    if log_file:
        with open(log_file, "a", encoding="utf-8") as f:
            f.write(f"[lua] {msg}\n")


def execute_pipeline(
    pipeline_cmd: str,
    log_file: Optional[Path] = None,
    dry_run: bool = False,
) -> Dict[str,
          Any]:
    """Execute a pipeline command and return result as JSON.

    Args:
        pipeline_cmd: Pipeline command string (e.g. "trim-file -path ... | add-file -store ...")
        log_file: Optional path to helper log file for logging
        dry_run: If True, log but don't execute

    Returns:
        JSON object with keys: success, stdout, stderr, error, returncode
    """
    try:
        if log_file:
            log_to_helper(f"[api] execute_pipeline cmd={pipeline_cmd}", log_file)

        if dry_run:
            return {
                "success": True,
                "stdout": "",
                "stderr": "DRY RUN - command not executed",
                "error": None,
                "returncode": 0,
                "cmd": pipeline_cmd,
            }

        # Call the CLI directly as subprocess
        import subprocess
        import shlex

        # Parse the pipeline command into separate arguments
        cmd_args = shlex.split(pipeline_cmd)

        result = subprocess.run(
            [sys.executable,
             "-m",
             "CLI"] + cmd_args,
            capture_output=True,
            text=True,
            cwd=str(_ROOT_DIR),
            env={
                **dict(__import__("os").environ),
                "MEDEIA_MPV_CALLER": "lua"
            },
        )

        if log_file:
            log_to_helper(
                f"[api] result returncode={result.returncode} len_stdout={len(result.stdout or '')} len_stderr={len(result.stderr or '')}",
                log_file,
            )
            if result.stderr:
                log_to_helper(f"[api] stderr: {result.stderr[:500]}", log_file)

        return {
            "success": result.returncode == 0,
            "stdout": result.stdout or "",
            "stderr": result.stderr or "",
            "error": None if result.returncode == 0 else result.stderr,
            "returncode": result.returncode,
            "cmd": pipeline_cmd,
        }

    except Exception as exc:
        msg = f"{type(exc).__name__}: {exc}"
        if log_file:
            log_to_helper(f"[api] exception {msg}", log_file)

        return {
            "success": False,
            "stdout": "",
            "stderr": str(exc),
            "error": msg,
            "returncode": 1,
            "cmd": pipeline_cmd,
        }


def handle_api_request(request_json: str, log_file: Optional[Path] = None) -> str:
    """Handle an API request from Lua and return JSON response.

    Request format:
    {
        "cmd": "execute_pipeline",
        "pipeline": "trim-file -path ... | add-file -store ...",
        ...
    }

    Response format: JSON with result of the operation.
    """
    try:
        request = json.loads(request_json)
        cmd = request.get("cmd")

        if cmd == "execute_pipeline":
            pipeline_cmd = request.get("pipeline", "")
            result = execute_pipeline(pipeline_cmd, log_file)
            return json.dumps(result)

        else:
            return json.dumps({
                "success": False,
                "error": f"Unknown command: {cmd}",
            })

    except Exception as exc:
        return json.dumps(
            {
                "success": False,
                "error": f"{type(exc).__name__}: {exc}",
            }
        )


if __name__ == "__main__":
    # When called from Lua via subprocess:
    # python mpv_lua_api.py <json-request>

    if len(sys.argv) < 2:
        print(json.dumps({
            "success": False,
            "error": "No request provided"
        }))
        sys.exit(1)

    request_json = sys.argv[1]
    log_file = Path(sys.argv[2]) if len(sys.argv) > 2 else None

    response = handle_api_request(request_json, log_file)
    print(response)
