"""
Async Utilities
===============
Safe async patterns for production use.

ADR-013: 此模組包含關鍵異步模式，修改前請先讀懂註解！
"""

import asyncio
from collections.abc import Coroutine
from typing import Any

from src.core.logging import get_logger

logger = get_logger("awoooi.async_utils")


def fire_and_forget(coro: Coroutine[Any, Any, Any], name: str | None = None) -> asyncio.Task[Any]:
    """
    安全的 fire-and-forget 模式。

    🔴 重要：不使用此函數的 asyncio.create_task() 會吞掉例外！

    Args:
        coro: 要執行的協程
        name: 任務名稱 (用於日誌)

    Returns:
        已建立的任務 (可忽略)

    Example:
        # ✅ 正確用法
        fire_and_forget(send_notification(user_id), name="notification")

        # ❌ 錯誤用法 (例外會被吞掉)
        asyncio.create_task(send_notification(user_id))
    """
    task = asyncio.create_task(coro, name=name)

    def _handle_exception(t: asyncio.Task[Any]) -> None:
        try:
            exc = t.exception()
            if exc is not None:
                logger.error(
                    "fire_and_forget_exception",
                    task_name=name or "unnamed",
                    error=str(exc),
                    error_type=type(exc).__name__,
                )
        except asyncio.CancelledError:
            logger.debug("fire_and_forget_cancelled", task_name=name or "unnamed")

    task.add_done_callback(_handle_exception)
    return task
