"""Structured logging configuration using loguru."""

import json
import sys
from pathlib import Path
from typing import Any

from loguru import logger

# Global flag to track if logging has been initialized
_initialized = False


def _serialize_json(record: dict[str, Any]) -> str:
    """Serialize log record to JSON format."""
    log_data = {
        "timestamp": record["time"].isoformat(),
        "level": record["level"].name,
        "message": record["message"],
        "module": record["name"],
        "function": record["function"],
        "line": record["line"],
    }

    # Add extra fields if present
    if record["extra"]:
        log_data["extra"] = dict(record["extra"])

    # Add exception info if present
    if record["exception"] is not None:
        log_data["exception"] = record["exception"]

    return json.dumps(log_data, ensure_ascii=False, default=str)


def _json_formatter(record: dict[str, Any]) -> str:
    """Format record for JSON output - returns the serialization plus newline."""
    record["extra"]["serialized"] = _serialize_json(record)
    return "{extra[serialized]}\n"


def setup_logging(
    log_level: str = "INFO",
    log_dir: str = "logs",
    console_format: str | None = None,
    enable_json: bool = True,
    enable_file: bool = True,
    rotation: str = "1 day",
    retention: str = "7 days",
    enqueue: bool = True,
) -> None:
    """Configure structured logging with loguru.

    Args:
        log_level: Minimum log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
        log_dir: Directory for log files
        console_format: Custom format for console output
        enable_json: Whether to enable JSON log file output
        enable_file: Whether to enable plain text log file output
        rotation: Log rotation period (e.g., "1 day", "500 MB")
        retention: Log retention period (e.g., "7 days", "1 week")
        enqueue: Whether to use async logging (recommended for production)
    """
    global _initialized

    if _initialized:
        logger.warning("Logging already initialized, skipping setup")
        return

    # Remove default handler
    logger.remove()

    # Default console format
    if console_format is None:
        console_format = (
            "<green>{time:HH:mm:ss}</green> | "
            "<level>{level: <8}</level> | "
            "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
            "<level>{message}</level>"
        )

    # Add console handler with colors
    logger.add(
        sys.stdout,
        format=console_format,
        level=log_level,
        colorize=True,
        enqueue=enqueue,
    )

    # Create log directory
    log_path = Path(log_dir)
    log_path.mkdir(parents=True, exist_ok=True)

    # Add plain text file handler
    if enable_file:
        logger.add(
            str(log_path / "openclaw_{time:YYYY-MM-DD}.log"),
            format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
            level=log_level,
            rotation=rotation,
            retention=retention,
            enqueue=enqueue,
            encoding="utf-8",
        )

    # Add JSON file handler
    if enable_json:
        logger.add(
            str(log_path / "openclaw_{time:YYYY-MM-DD}.jsonl"),
            format=_json_formatter,
            level=log_level,
            rotation=rotation,
            retention=retention,
            enqueue=enqueue,
            encoding="utf-8",
        )

    _initialized = True
    logger.info(f"Logging initialized with level {log_level}, log_dir: {log_path.absolute()}")


def get_logger(name: str):
    """Get a logger instance for a specific module.

    Args:
        name: Module name for the logger

    Returns:
        Configured logger instance
    """
    return logger.bind(name=name)


def set_module_level(module_name: str, level: str) -> None:
    """Set log level for a specific module.

    Args:
        module_name: Name of the module
        level: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    """
    # Note: loguru doesn't have built-in per-module levels like stdlib logging.
    # This is a placeholder for future enhancement using filters.
    logger.info(f"Setting log level for {module_name} to {level}")


def get_logs_dir() -> Path:
    """Get the default logs directory path."""
    return Path("logs").absolute()


# Convenience re-exports
__all__ = [
    "setup_logging",
    "get_logger",
    "set_module_level",
    "get_logs_dir",
    "logger",
]
