import asyncio
from typing import Any

from loguru import logger

from request_decorator_handlers.logging.request_logger import RequestLogger


class DummyResponse:
    """Простая заглушка ответа для тестов RequestLogger."""

    def __init__(self, url: str = "https://example.com", status_code: int = 200):
        self.url = url
        self.status_code = status_code
        self.headers = {"content-type": "application/json"}

    def json(self) -> dict[str, Any]:
        return {"status": "ok"}


async def _run_logged_call() -> DummyResponse:
    @RequestLogger.log(action="TEST")
    async def fetch(url: str) -> DummyResponse:
        await asyncio.sleep(0)
        return DummyResponse(url=url)

    return await fetch("https://example.com")


def test_request_logger_default_silent():
    captured: list[str] = []
    sink_id = logger.add(lambda msg: captured.append(msg), format="{message}")
    try:
        asyncio.run(_run_logged_call())
    finally:
        logger.remove(sink_id)
    assert captured == []


def test_request_logger_emits_after_enable():
    RequestLogger.enable()
    captured: list[str] = []
    sink_id = logger.add(lambda msg: captured.append(msg), format="{message}")
    try:
        asyncio.run(_run_logged_call())
    finally:
        logger.remove(sink_id)
        RequestLogger.disable()
    assert captured, "Expected log output when RequestLogger is enabled"


def test_request_logger_respects_loguru_disable():
    RequestLogger.enable()
    captured: list[str] = []
    sink_id = logger.add(lambda msg: captured.append(msg), format="{message}")
    try:
        asyncio.run(_run_logged_call())
        baseline = len(captured)
        logger.disable("request_decorator_handlers")
        asyncio.run(_run_logged_call())
        after = len(captured)
    finally:
        logger.remove(sink_id)
        logger.enable("request_decorator_handlers")
        RequestLogger.disable()
    assert after == baseline, "Logs should be muted after loguru.disable()"


def test_request_logger_muted_context():
    RequestLogger.enable()
    captured: list[str] = []
    sink_id = logger.add(lambda msg: captured.append(msg), format="{message}")
    try:
        asyncio.run(_run_logged_call())
        captured.clear()
        with RequestLogger.muted():
            asyncio.run(_run_logged_call())
    finally:
        logger.remove(sink_id)
        RequestLogger.disable()
    assert captured == []
