"""
Task-related message handlers.

Handles PFC task execution and task status management operations.
"""

from typing import Any, Dict

from .context import ServerContext
from .helpers import truncate_message, require_field


async def handle_pfc_task(ctx, data):
    # type: (ServerContext, Dict[str, Any]) -> Dict[str, Any]
    """
    Handle pfc_task message - execute Python script from file path.

    Args:
        ctx: Server context with dependencies
        data: Message data containing:
            - request_id: Request identifier
            - session_id: Session identifier (default: "default")
            - script_path: Path to Python script
            - description: Task description
            - task_id: Required backend-generated task ID (6-char hex)

    Returns:
        Response dict with task execution result
    """
    request_id = data.get("request_id", "unknown")

    script_path, err = require_field(data, "script_path", request_id)
    if err:
        return err

    # task_id is required (must be generated by backend)
    task_id, err = require_field(data, "task_id", request_id)
    if err:
        return err

    session_id = data.get("session_id", "default")
    description = data.get("description", "")

    result = await ctx.script_runner.run(
        session_id, script_path, description, task_id=task_id
    )

    # Truncate message before sending
    if "message" in result:
        result["message"] = truncate_message(result["message"])

    return {
        "type": "result",
        "request_id": request_id,
        **result
    }


async def handle_check_task_status(ctx, data):
    # type: (ServerContext, Dict[str, Any]) -> Dict[str, Any]
    """
    Handle check_task_status message.

    Args:
        ctx: Server context with dependencies
        data: Message data containing:
            - request_id: Request identifier
            - task_id: Task ID to check

    Returns:
        Response dict with task status
    """
    request_id = data.get("request_id", "unknown")

    task_id, err = require_field(data, "task_id", request_id)
    if err:
        return err

    result = ctx.task_manager.get_task_status(task_id)

    # Truncate message before sending
    if "message" in result:
        result["message"] = truncate_message(result["message"])

    return {
        "type": "result",
        "request_id": request_id,
        **result
    }


async def handle_list_tasks(ctx, data):
    # type: (ServerContext, Dict[str, Any]) -> Dict[str, Any]
    """
    Handle list_tasks message.

    Args:
        ctx: Server context with dependencies
        data: Message data containing:
            - request_id: Request identifier
            - session_id: Optional session filter
            - offset: Pagination offset (default: 0)
            - limit: Optional pagination limit

    Returns:
        Response dict with task list
    """
    request_id = data.get("request_id", "unknown")
    session_id = data.get("session_id")  # Optional session filter
    offset = data.get("offset", 0)
    limit = data.get("limit")

    result = ctx.task_manager.list_all_tasks(
        session_id=session_id,
        offset=offset,
        limit=limit
    )

    return {
        "type": "result",
        "request_id": request_id,
        **result
    }


async def handle_interrupt_task(ctx, data):
    # type: (ServerContext, Dict[str, Any]) -> Dict[str, Any]
    """
    Handle interrupt_task message - request interrupt for a running task.

    Only sets interrupt flag for tasks that are actually running or pending.
    Returns error for completed/failed/interrupted tasks to prevent flag leaks.

    Args:
        ctx: Server context with dependencies
        data: Message data containing:
            - request_id: Request identifier
            - task_id: Task ID to interrupt

    Returns:
        Response dict with interrupt request result
    """
    from ..signals import request_interrupt

    request_id = data.get("request_id", "unknown")

    task_id, err = require_field(data, "task_id", request_id)
    if err:
        return err

    # Check if task exists and is interruptible
    task = ctx.task_manager.tasks.get(task_id)
    if not task:
        return {
            "type": "result",
            "request_id": request_id,
            "status": "error",
            "message": "Task not found: {}".format(task_id),
            "data": {"task_id": task_id, "interrupt_requested": False}
        }

    # Only allow interrupt for pending/running tasks
    task_status = task.status
    if task_status not in ("pending", "running"):
        return {
            "type": "result",
            "request_id": request_id,
            "status": "error",
            "message": "Task already in terminal state: {} (status: {})".format(task_id, task_status),
            "data": {"task_id": task_id, "status": task_status, "interrupt_requested": False}
        }

    # Request interrupt (will be checked by PFC callback)
    success = request_interrupt(task_id)
    if success:
        return {
            "type": "result",
            "request_id": request_id,
            "status": "success",
            "message": "Interrupt requested for task: {}".format(task_id),
            "data": {"task_id": task_id, "interrupt_requested": True}
        }
    else:
        return {
            "type": "result",
            "request_id": request_id,
            "status": "error",
            "message": "Failed to request interrupt",
            "data": None
        }
