"""Debug Oracle CLI - main entry point."""
import argparse
import logging
import sys
from datetime import datetime, timezone

from .config import OracleConfig
from .ingest import DockerIngestor, SystemdIngestor, GitIngestor, SystemMetricsIngestor
from .reason import ReasoningEngine
from .output import OutputFormatter
from .models import Severity
from .watchdog import Watchdog


def setup_logging(verbose: int = 0):
    """Configure logging based on verbosity."""
    level = {0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG}.get(verbose, logging.INFO)
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
        datefmt="%H:%M:%S",
    )


def cmd_investigate(args, config: OracleConfig):
    """Investigate a problem."""
    logger = logging.getLogger(__name__)
    
    # Collect data
    logger.info("Collecting data...")
    
    docker = DockerIngestor()
    systemd = SystemdIngestor()
    git = GitIngestor()
    metrics = SystemMetricsIngestor()
    
    # Docker logs
    containers = args.containers if args.containers else config.ingest.containers
    logs = docker.get_all_logs(
        containers=containers or None,
        since_minutes=config.ingest.lookback_minutes,
        tail=config.ingest.max_log_lines
    )
    
    # Systemd logs
    system_logs = systemd.get_logs(
        since_minutes=config.ingest.lookback_minutes,
        priority=args.priority or "warning"
    )
    logs.extend(system_logs)
    
    # Metrics
    metric_snapshots = []
    if config.ingest.include_metrics:
        metric_snapshots.append(metrics.get_snapshot())
    
    # Git changes
    git_changes = []
    if args.repos:
        for repo in args.repos:
            changes = git.get_recent_commits(
                repo,
                since_minutes=config.ingest.lookback_minutes * 24  # Git looks further back
            )
            git_changes.extend(changes)
    
    logger.info(
        "Collected: %d logs, %d metrics, %d git changes",
        len(logs), len(metric_snapshots), len(git_changes)
    )
    
    # Show severity summary
    formatter = OutputFormatter(config.output_format)
    formatter.print_severity_summary(logs)
    
    # Run analysis
    query = args.query
    if not query:
        # Auto-generate query from errors
        errors = [l for l in logs if l.severity in (Severity.ERROR, Severity.CRITICAL)]
        if errors:
            recent_errors = [e.message[:100] for e in errors[:5]]
            query = f"System failure detected. Recent errors: {'; '.join(recent_errors)}"
        else:
            query = "Investigate recent system activity and identify potential issues."
    
    try:
        engine = ReasoningEngine(config.llm)
        investigation = engine.analyze(query, logs, metric_snapshots, git_changes)
        formatter.print_investigation(investigation)
        engine.close()
    except (RuntimeError, TimeoutError) as e:
        print(f"\n[Error] Analysis failed: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_triage(args, config: OracleConfig):
    """Quick triage - assess situation before deep dive."""
    logger = logging.getLogger(__name__)
    
    docker = DockerIngestor()
    logs = docker.get_all_logs(
        containers=args.containers or None,
        since_minutes=30,
        tail=200
    )
    
    query = args.query or "Triage recent system issues"
    
    try:
        engine = ReasoningEngine(config.llm)
        result = engine.triage(query, logs)
        
        formatter = OutputFormatter(config.output_format)
        if formatter.format == "rich":
            from rich.console import Console
            from rich.panel import Panel
            from rich.markdown import Markdown
            console = Console()
            console.print("\n[bold cyan]⚙ Quick Triage[/bold cyan]\n")
            console.print(Panel(Markdown(result), title="Assessment", border_style="yellow"))
            console.print()
        else:
            print(f"\nQuick Triage: {query}\n")
            print(result)
        
        engine.close()
    except (RuntimeError, TimeoutError) as e:
        print(f"\n[Error] Triage failed: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_watch(args, config: OracleConfig):
    """Start watchdog monitoring."""
    import signal
    import sys
    import threading
    
    # Import watchdog here to avoid circular imports
    from .watchdog import Watchdog
    
    # Determine alert target
    alert_target = args.alert or config.alert_target
    
    watchdog = Watchdog(
        check_interval=args.interval,
        containers=args.containers or [],
        metrics_thresholds={
            "cpu_critical": args.cpu_threshold or 90.0,
            "memory_critical": args.mem_threshold or 90.0,
            "disk_critical": args.disk_threshold or 90.0,
        },
        alert_target=alert_target,
        llm_config=config.llm,
        state_dir=config.state_dir,
    )
    
    # Handle shutdown gracefully
    def shutdown_handler(signum, frame):
        print("\nShutting down watchdog...")
        watchdog.stop()
        sys.exit(0)
    
    signal.signal(signal.SIGINT, shutdown_handler)
    signal.signal(signal.SIGTERM, shutdown_handler)
    
    print(f"Debug Oracle Watchdog started")
    print(f"  Check interval: {args.interval}s")
    print(f"  Alert target: {alert_target}")
    print(f"  State: {config.state_dir}")
    print(f"  Press Ctrl+C to stop\n")
    
    # Run in main thread (blocking)
    watchdog.run()


def cmd_status(args, config: OracleConfig):
    """Show system status overview."""
    docker = DockerIngestor()
    metrics = SystemMetricsIngestor()
    systemd = SystemdIngestor()
    
    snapshot = metrics.get_snapshot()
    containers = docker.get_containers()
    failed = systemd.get_failed_units()
    
    formatter = OutputFormatter(config.output_format)
    
    if formatter.format == "rich":
        from rich.console import Console
        console = Console()
        
        console.print("\n[bold cyan]⚙ System Status[/bold cyan]\n")
        
        # Metrics
        console.print("[bold]System Metrics:[/bold]")
        console.print(f"  CPU: {snapshot.cpu_percent:.1f}%")
        console.print(f"  Memory: {snapshot.memory_percent:.1f}%")
        console.print(f"  Disk: {snapshot.disk_percent:.1f}%")
        console.print(f"  Load: {snapshot.load_avg}")
        console.print()
        
        # Containers
        if containers:
            console.print(f"[bold]Running Containers ({len(containers)}):[/bold]")
            for c in containers:
                health = docker.get_health(c)
                status = health.get("status", "unknown")
                color = "green" if "running" in status else "red"
                console.print(f"  [{color}]{c}[/]: {status}")
            console.print()
        
        # Failed units
        if failed:
            console.print(f"[bold red]Failed Units ({len(failed)}):[/bold red]")
            for unit in failed:
                console.print(f"  - {unit['unit']} ({unit['active']})")
            console.print()
    
    else:
        print("\nSystem Status:")
        print(f"  CPU: {snapshot.cpu_percent:.1f}%")
        print(f"  Memory: {snapshot.memory_percent:.1f}%")
        print(f"  Disk: {snapshot.disk_percent:.1f}%")
        print(f"  Load: {snapshot.load_avg}")
        print(f"\nContainers: {', '.join(containers)}")
        if failed:
            print(f"\nFailed: {', '.join(u['unit'] for u in failed)}")
        print()


def main():
    """CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="oracle",
        description="Debug Oracle - causal debugging that explains why things broke",
    )
    
    parser.add_argument("-v", "--verbose", action="count", default=0, help="Verbosity level")
    parser.add_argument("--llm-url", default=None, help="LLM API base URL")
    parser.add_argument("--format", choices=["rich", "text", "json"], default="rich", help="Output format")
    
    subparsers = parser.add_subparsers(dest="command", help="Command")
    
    # Investigate
    inv_parser = subparsers.add_parser("investigate", help="Investigate a problem")
    inv_parser.add_argument("query", nargs="?", default=None, help="What to investigate")
    inv_parser.add_argument("-c", "--containers", nargs="*", help="Docker containers to check")
    inv_parser.add_argument("-r", "--repos", nargs="*", help="Git repos to check")
    inv_parser.add_argument("-p", "--priority", choices=["info", "warning", "error"], help="Log priority filter")
    inv_parser.set_defaults(func=cmd_investigate)
    
    # Triage
    triage_parser = subparsers.add_parser("triage", help="Quick triage assessment")
    triage_parser.add_argument("query", nargs="?", default=None, help="What to triage")
    triage_parser.add_argument("-c", "--containers", nargs="*", help="Docker containers to check")
    triage_parser.set_defaults(func=cmd_triage)
    
    # Status
    status_parser = subparsers.add_parser("status", help="System status overview")
    status_parser.set_defaults(func=cmd_status)
    
    # Watch
    watch_parser = subparsers.add_parser("watch", help="Start watchdog monitoring")
    watch_parser.add_argument("-i", "--interval", type=int, default=300, help="Check interval in seconds (default: 300)")
    watch_parser.add_argument("-c", "--containers", nargs="*", help="Docker containers to monitor")
    watch_parser.add_argument("-a", "--alert", default="telegram", help="Alert target (default: telegram)")
    watch_parser.add_argument("--cpu-threshold", type=float, default=90.0, help="CPU critical threshold %")
    watch_parser.add_argument("--mem-threshold", type=float, default=90.0, help="Memory critical threshold %")
    watch_parser.add_argument("--disk-threshold", type=float, default=90.0, help="Disk critical threshold %")
    watch_parser.set_defaults(func=cmd_watch)
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        sys.exit(0)
    
    # Setup
    setup_logging(args.verbose)
    config = OracleConfig(output_format=args.format)
    if args.llm_url:
        config.llm.base_url = args.llm_url
    
    # Run command
    args.func(args, config)


if __name__ == "__main__":
    main()
