"""
Doit Agent - Logging System
Structured logging to file, stderr, and SQLite audit log.
"""
from __future__ import annotations

import asyncio
import logging
import logging.handlers
import sys
from pathlib import Path
from typing import Optional

from core.config import LOG_DIR, APP_LOG


class AsyncDBLogHandler(logging.Handler):
    """Async log handler that writes to SQLite via a queue."""

    def __init__(self):
        super().__init__()
        self._queue: asyncio.Queue = asyncio.Queue(maxsize=1000)
        self._task: Optional[asyncio.Task] = None

    def emit(self, record: logging.LogRecord) -> None:
        try:
            self._queue.put_nowait(record)
        except asyncio.QueueFull:
            pass

    async def start(self):
        self._task = asyncio.create_task(self._worker())

    async def stop(self):
        if self._task:
            self._task.cancel()

    async def _worker(self):
        from persistence.database import get_db
        while True:
            try:
                record = await self._queue.get()
                db = await get_db()
                await db.log_insert(
                    level=record.levelname,
                    module=record.name,
                    message=self.format(record)[:2000],
                )
                self._queue.task_done()
            except asyncio.CancelledError:
                break
            except Exception:
                pass


_db_handler: Optional[AsyncDBLogHandler] = None


def setup_logging(level: str = "INFO") -> AsyncDBLogHandler:
    """Configure logging for the application."""
    global _db_handler

    LOG_DIR.mkdir(parents=True, exist_ok=True)

    fmt = logging.Formatter(
        "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )

    root = logging.getLogger("doit")
    root.setLevel(getattr(logging, level.upper(), logging.INFO))

    # File handler with rotation
    fh = logging.handlers.RotatingFileHandler(
        APP_LOG, maxBytes=10 * 1024 * 1024, backupCount=5, encoding="utf-8"
    )
    fh.setFormatter(fmt)
    root.addHandler(fh)

    # Stderr handler
    sh = logging.StreamHandler(sys.stderr)
    sh.setFormatter(fmt)
    sh.setLevel(logging.WARNING)
    root.addHandler(sh)

    # Async DB handler
    _db_handler = AsyncDBLogHandler()
    _db_handler.setFormatter(fmt)
    root.addHandler(_db_handler)

    return _db_handler


def get_db_handler() -> Optional[AsyncDBLogHandler]:
    return _db_handler
