"""Risk display helpers and progress bar utilities for BADAS."""

from typing import Any, Dict, Optional

from badas.visualization.charts import VisualizationConfig


def is_notebook() -> bool:
    """Detect if running in a Jupyter notebook."""
    try:
        from IPython import get_ipython
        shell = get_ipython().__class__.__name__
        if shell == 'ZMQInteractiveShell':
            return True  # Jupyter notebook or qtconsole
        elif shell == 'TerminalInteractiveShell':
            return False  # Terminal IPython
        else:
            return False
    except (NameError, AttributeError):
        return False


class _DummyPbar:
    """Dummy progress bar when tqdm is not available."""
    def __init__(self, iterable=None, total=None, **kwargs):
        self.iterable = iterable
        self.n = 0
        self.total = total

    def __iter__(self):
        if self.iterable is not None:
            for item in self.iterable:
                yield item
                self.n += 1

    def update(self, n=1):
        self.n += n

    def close(self):
        pass

    def set_postfix(self, *args, **kwargs):
        pass


def get_progress_bar(iterable=None, total=None, desc=None, disable=False, **kwargs):
    """
    Get appropriate progress bar based on environment.

    Args:
        iterable: Iterable to wrap
        total: Total iterations (if iterable doesn't have len)
        desc: Description prefix
        disable: If True, disable progress bar (quiet mode)
        **kwargs: Additional arguments passed to tqdm

    Returns:
        tqdm progress bar instance
    """
    # Try to use tqdm.auto which handles notebook detection properly
    try:
        from tqdm.auto import tqdm
        return tqdm(iterable, total=total, desc=desc, disable=disable, **kwargs)
    except ImportError:
        pass

    # Fall back to regular tqdm
    try:
        from tqdm import tqdm
        return tqdm(iterable, total=total, desc=desc, disable=disable, **kwargs)
    except ImportError:
        pass

    # No tqdm available - return dummy
    return _DummyPbar(iterable=iterable, total=total)


def get_risk_color(probability: float, config: VisualizationConfig = None) -> tuple:
    """Get RGB color based on risk probability."""
    if config is None:
        config = VisualizationConfig()

    if probability < config.caution_threshold:
        return config.safe_color
    elif probability < config.danger_threshold:
        return config.caution_color
    else:
        return config.danger_color


def get_risk_level(probability: float, config: VisualizationConfig = None) -> str:
    """Get risk level string."""
    if config is None:
        config = VisualizationConfig()

    if probability < config.caution_threshold:
        return "SAFE"
    elif probability < config.danger_threshold:
        return "CAUTION"
    else:
        return "DANGER"


def format_risk_level(probability: float) -> str:
    """Get detailed risk level string for display."""
    if probability >= 0.75:
        return "CRITICAL"
    elif probability >= 0.65:
        return "HIGH"
    elif probability >= 0.4:
        return "MEDIUM-HIGH"
    elif probability >= 0.3:
        return "MEDIUM"
    elif probability >= 0.2:
        return "MEDIUM-LOW"
    return "LOW"


def get_risk_emoji(probability: float, use_color: bool = True, config: VisualizationConfig = None) -> str:
    """
    Get risk indicator for terminal output.

    Args:
        probability: Risk probability (0-1)
        use_color: If True, use ANSI color codes for terminal
        config: VisualizationConfig for thresholds (defaults to VisualizationConfig())

    Returns:
        Colored or plain emoji indicator
    """
    if config is None:
        config = VisualizationConfig()
    if use_color:
        if probability >= config.danger_threshold:
            return "\033[91m●\033[0m"  # Red
        elif probability >= config.caution_threshold:
            return "\033[93m●\033[0m"  # Yellow
        else:
            return "\033[92m●\033[0m"  # Green
    else:
        if probability >= config.danger_threshold:
            return "🔴"
        elif probability >= config.caution_threshold:
            return "🟠"
        else:
            return "🟢"


def print_prediction(pred: Dict[str, Any], use_color: Optional[bool] = None) -> None:
    """
    Print formatted prediction line.

    Auto-detects environment: uses ANSI colors for terminal, emoji for notebooks.

    Args:
        pred: Prediction dict with keys: probability, raw_probability,
              timestamp, latency_ms, frame_index
        use_color: If None (default), auto-detect based on environment.
                   If True, use ANSI color codes. If False, use emoji.
    """
    if use_color is None:
        use_color = not is_notebook()

    prob = pred['probability']
    raw_prob = pred.get('raw_probability', prob)
    timestamp = pred['timestamp']
    latency = pred.get('latency_ms', 0)
    frame_idx = pred.get('frame_index', 0)

    emoji = get_risk_emoji(prob, use_color)
    level = format_risk_level(prob)

    if abs(prob - raw_prob) > 0.02:
        prob_str = f"Risk: {prob:5.1%} (raw: {raw_prob:5.1%})"
    else:
        prob_str = f"Risk: {prob:5.1%}"

    print(f"{emoji} Frame {frame_idx:4d} | t={timestamp:6.2f}s | {prob_str} | {level:11s} | {latency:.1f}ms")
