"""
Structured Logging

JSON-formatted structured logging for ALTRUS system.
"""

import json
import logging
import time
from typing import Dict, Any, Optional
from datetime import datetime
from enum import Enum


class LogLevel(Enum):
    """Log levels"""
    DEBUG = "DEBUG"
    INFO = "INFO"
    WARNING = "WARNING"
    ERROR = "ERROR"
    CRITICAL = "CRITICAL"


class StructuredLogger:
    """
    Structured logger that outputs JSON-formatted logs.

    Features:
    - JSON output for easy parsing
    - Contextual fields (module_id, intent_id, etc.)
    - Timestamp in ISO format
    - Severity levels
    """

    def __init__(self, name: str = "altrus", log_file: Optional[str] = None):
        self.name = name
        self.logger = logging.getLogger(name)
        self.logger.setLevel(logging.DEBUG)

        # Create formatter
        formatter = logging.Formatter('%(message)s')

        # Console handler
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter)
        self.logger.addHandler(console_handler)

        # File handler if specified
        if log_file:
            file_handler = logging.FileHandler(log_file)
            file_handler.setFormatter(formatter)
            self.logger.addHandler(file_handler)

        # Context fields
        self._context: Dict[str, Any] = {}

    def set_context(self, **kwargs):
        """Set context fields that will be included in all logs"""
        self._context.update(kwargs)

    def clear_context(self):
        """Clear all context fields"""
        self._context.clear()

    def _format_log(
        self,
        level: LogLevel,
        message: str,
        **extra_fields
    ) -> str:
        """Format log entry as JSON"""
        log_entry = {
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "level": level.value,
            "logger": self.name,
            "message": message,
            **self._context,
            **extra_fields
        }
        return json.dumps(log_entry)

    def debug(self, message: str, **extra_fields):
        """Log debug message"""
        log_str = self._format_log(LogLevel.DEBUG, message, **extra_fields)
        self.logger.debug(log_str)

    def info(self, message: str, **extra_fields):
        """Log info message"""
        log_str = self._format_log(LogLevel.INFO, message, **extra_fields)
        self.logger.info(log_str)

    def warning(self, message: str, **extra_fields):
        """Log warning message"""
        log_str = self._format_log(LogLevel.WARNING, message, **extra_fields)
        self.logger.warning(log_str)

    def error(self, message: str, **extra_fields):
        """Log error message"""
        log_str = self._format_log(LogLevel.ERROR, message, **extra_fields)
        self.logger.error(log_str)

    def critical(self, message: str, **extra_fields):
        """Log critical message"""
        log_str = self._format_log(LogLevel.CRITICAL, message, **extra_fields)
        self.logger.critical(log_str)

    def log_intent_event(
        self,
        event_type: str,
        intent_id: str,
        intent_name: str,
        **extra_fields
    ):
        """Log intent-related event"""
        self.info(
            f"Intent event: {event_type}",
            event_type=event_type,
            intent_id=intent_id,
            intent_name=intent_name,
            **extra_fields
        )

    def log_fault_event(
        self,
        module_id: str,
        fault_type: str,
        severity: str,
        **extra_fields
    ):
        """Log fault-related event"""
        self.error(
            f"Fault detected: {fault_type}",
            module_id=module_id,
            fault_type=fault_type,
            severity=severity,
            **extra_fields
        )

    def log_state_transition(
        self,
        from_state: str,
        to_state: str,
        reason: str,
        **extra_fields
    ):
        """Log system state transition"""
        self.info(
            f"State transition: {from_state} → {to_state}",
            from_state=from_state,
            to_state=to_state,
            reason=reason,
            **extra_fields
        )

    def log_ledger_event(
        self,
        event_type: str,
        block_index: int,
        **extra_fields
    ):
        """Log blockchain ledger event"""
        self.info(
            f"Ledger event: {event_type}",
            event_type=event_type,
            block_index=block_index,
            **extra_fields
        )


# Global logger instance
_global_logger: Optional[StructuredLogger] = None


def get_logger(name: str = "altrus") -> StructuredLogger:
    """Get or create global structured logger"""
    global _global_logger
    if _global_logger is None:
        _global_logger = StructuredLogger(name)
    return _global_logger


def configure_logging(log_file: Optional[str] = None, level: str = "INFO"):
    """Configure global logging"""
    global _global_logger
    _global_logger = StructuredLogger("altrus", log_file=log_file)

    # Set level
    level_map = {
        "DEBUG": logging.DEBUG,
        "INFO": logging.INFO,
        "WARNING": logging.WARNING,
        "ERROR": logging.ERROR,
        "CRITICAL": logging.CRITICAL
    }
    _global_logger.logger.setLevel(level_map.get(level, logging.INFO))


# Example usage
if __name__ == "__main__":
    logger = get_logger()

    logger.info("System starting", component="kernel")
    logger.set_context(session_id="abc123")

    logger.log_intent_event(
        "INTENT_SUBMITTED",
        intent_id="intent_001",
        intent_name="navigate_to_room",
        priority="HIGH"
    )

    logger.log_fault_event(
        module_id="nav_module",
        fault_type="TIMEOUT",
        severity="SOFT",
        recovery_attempted=True
    )

    logger.log_state_transition(
        from_state="READY",
        to_state="RUNNING",
        reason="System started successfully"
    )
