"""
BGF Agents CLI

Command-line interface for running and managing BGF agents.

Usage:
    bgf-agents run <agent> [options]
    bgf-agents list
    bgf-agents health
    bgf-agents config [show|set]
"""

from __future__ import annotations

import argparse
import asyncio
import json
import logging
import sys
from typing import Any

from .config import Config, get_config, reload_config


def setup_logging(level: str = "INFO") -> None:
    """Setup logging configuration."""
    logging.basicConfig(
        level=getattr(logging, level.upper()),
        format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )


def cmd_list(args: argparse.Namespace) -> int:
    """List available agents and tools."""
    from .orchestrator import MasterOrchestratorAgent
    from .healer import HealerAgent
    from .governor import GovernorAgent
    from .agents import CollectorAgent, AnalyticsAgent
    from .tools import ALL_TOOLS_EXTENDED

    print("\n=== BGF Agents ===\n")

    agents = [
        ("orchestrator", "Master Orchestrator", "System health monitoring and ETL orchestration"),
        ("healer", "Healer Agent", "Self-healing with circuit breakers and anomaly detection"),
        ("governor", "Governor Agent", "Data governance, quality, lineage, and contracts"),
        ("collector", "Collector Agent", "Multi-tier data collection (HTTP/JS/Firecrawl/Browser)"),
        ("analytics", "Analytics Agent", "Statistical analysis, trends, anomalies, reports"),
    ]

    print("Available Agents:")
    print("-" * 60)
    for name, title, desc in agents:
        print(f"  {name:12} - {title}")
        print(f"               {desc}")
        print()

    print(f"\nTotal Tools: {len(ALL_TOOLS_EXTENDED)}")

    if args.verbose:
        print("\n=== Tools ===\n")
        for i, tool in enumerate(ALL_TOOLS_EXTENDED, 1):
            print(f"  {i:2}. {tool['name']}: {tool['description'][:50]}...")

    return 0


def cmd_health(args: argparse.Namespace) -> int:
    """Check system health."""
    import asyncio

    async def check_health():
        results = {"status": "healthy", "checks": {}}

        # Check database
        try:
            config = get_config()
            import asyncpg
            conn = await asyncpg.connect(config.database.url, timeout=5)
            await conn.execute("SELECT 1")
            await conn.close()
            results["checks"]["database"] = {"status": "ok"}
        except Exception as e:
            results["checks"]["database"] = {"status": "error", "message": str(e)}
            results["status"] = "degraded"

        # Check Redis
        try:
            import redis.asyncio as redis
            r = redis.from_url(config.redis.url)
            await r.ping()
            await r.close()
            results["checks"]["redis"] = {"status": "ok"}
        except Exception as e:
            results["checks"]["redis"] = {"status": "error", "message": str(e)}
            results["status"] = "degraded"

        # Check LLM API
        try:
            if config.llm.api_key:
                results["checks"]["llm"] = {
                    "status": "ok",
                    "provider": config.llm.provider,
                    "model": config.llm.model,
                }
            else:
                results["checks"]["llm"] = {"status": "warning", "message": "No API key configured"}
        except Exception as e:
            results["checks"]["llm"] = {"status": "error", "message": str(e)}

        return results

    results = asyncio.run(check_health())

    print("\n=== System Health ===\n")
    print(f"Status: {results['status'].upper()}")
    print()

    for check, data in results["checks"].items():
        status = data.get("status", "unknown")
        icon = "✅" if status == "ok" else "⚠️" if status == "warning" else "❌"
        print(f"  {icon} {check}: {status}")
        if "message" in data:
            print(f"     {data['message']}")
        if "provider" in data:
            print(f"     Provider: {data['provider']}, Model: {data['model']}")

    print()
    return 0 if results["status"] == "healthy" else 1


def cmd_run(args: argparse.Namespace) -> int:
    """Run an agent."""
    agent_name = args.agent.lower()

    # Setup logging
    setup_logging(args.log_level)
    logger = logging.getLogger("bgf-agents")

    # Load config
    config = reload_config(args.config) if args.config else get_config()

    print(f"\n=== Running {agent_name} Agent ===\n")

    async def run_agent():
        if agent_name == "orchestrator":
            from .orchestrator import MasterOrchestratorAgent
            agent = MasterOrchestratorAgent(config=config)

            if args.task == "health":
                result = await agent.check_all_health()
            elif args.task == "etl":
                result = await agent.run_etl(args.module or "all")
            else:
                result = await agent.check_all_health()

        elif agent_name == "healer":
            from .healer import HealerAgent
            agent = HealerAgent(config=config)

            if args.task == "detect":
                result = agent.detect_anomalies([1, 2, 3, 100, 4, 5])  # Demo
            elif args.task == "circuits":
                result = agent.list_circuits()
            else:
                result = {"status": "ready", "circuits": agent.list_circuits()}

        elif agent_name == "governor":
            from .governor import GovernorAgent
            agent = GovernorAgent(config=config)

            if args.task == "quality":
                result = agent.check_data_quality(args.table or "demo")
            elif args.task == "lineage":
                result = agent.get_lineage(args.entity or "demo")
            else:
                result = {"status": "ready", "contracts": agent.list_contracts()}

        elif agent_name == "collector":
            from .agents import CollectorAgent
            agent = CollectorAgent(config=config)

            if args.url:
                result = await agent.smart_collect(args.url)
                result = {
                    "success": result.success,
                    "source": result.source,
                    "tier": result.tier.value,
                    "records": result.records_collected,
                    "duration_ms": result.duration_ms,
                    "error": result.error,
                }
            else:
                result = {"status": "ready", "stats": agent.get_collection_stats()}

        elif agent_name == "analytics":
            from .agents import AnalyticsAgent
            agent = AnalyticsAgent(config=config)

            if args.data:
                data = json.loads(args.data)
                result = agent.analyze_statistics(data)
                result = {
                    "success": result.success,
                    "summary": result.summary,
                    "metrics": result.metrics,
                    "insights": result.insights,
                }
            else:
                result = {"status": "ready"}

        else:
            return {"error": f"Unknown agent: {agent_name}"}

        return result

    try:
        result = asyncio.run(run_agent())
        print(json.dumps(result, indent=2, default=str))
        return 0
    except KeyboardInterrupt:
        print("\nInterrupted")
        return 130
    except Exception as e:
        logger.error(f"Error running agent: {e}")
        print(f"\nError: {e}")
        return 1


def cmd_config(args: argparse.Namespace) -> int:
    """Manage configuration."""
    config = get_config()

    if args.action == "show":
        print("\n=== Configuration ===\n")
        print(json.dumps(config.to_dict(), indent=2))
        return 0

    elif args.action == "set":
        if not args.key or not args.value:
            print("Error: --key and --value required for 'set' action")
            return 1

        # For now, just show what would be set
        print(f"Would set {args.key} = {args.value}")
        print("Note: Use environment variables or config file to persist settings")
        return 0

    elif args.action == "validate":
        print("\n=== Configuration Validation ===\n")

        issues = []

        if not config.llm.api_key:
            issues.append("LLM API key not configured (set ANTHROPIC_API_KEY or OPENAI_API_KEY)")

        if config.database.url == "postgresql://localhost:5432/postgres":
            issues.append("Using default database URL - consider configuring for production")

        if issues:
            print("Issues found:")
            for issue in issues:
                print(f"  ⚠️  {issue}")
        else:
            print("✅ Configuration looks good!")

        return 0 if not issues else 1

    else:
        print(f"Unknown action: {args.action}")
        return 1


def main() -> int:
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="bgf-agents",
        description="BGF Agents - Autonomous Data Factory Agents",
    )
    parser.add_argument(
        "--version",
        action="version",
        version="bgf-agents 0.1.0",
    )

    subparsers = parser.add_subparsers(dest="command", help="Commands")

    # list command
    list_parser = subparsers.add_parser("list", help="List available agents and tools")
    list_parser.add_argument("-v", "--verbose", action="store_true", help="Show all tools")

    # health command
    health_parser = subparsers.add_parser("health", help="Check system health")

    # run command
    run_parser = subparsers.add_parser("run", help="Run an agent")
    run_parser.add_argument("agent", help="Agent to run (orchestrator, healer, governor, collector, analytics)")
    run_parser.add_argument("-c", "--config", help="Path to config file")
    run_parser.add_argument("-t", "--task", help="Task to execute")
    run_parser.add_argument("-m", "--module", help="ETL module (for orchestrator)")
    run_parser.add_argument("--table", help="Table name (for governor)")
    run_parser.add_argument("--entity", help="Entity name (for lineage)")
    run_parser.add_argument("--url", help="URL to collect (for collector)")
    run_parser.add_argument("--data", help="JSON data (for analytics)")
    run_parser.add_argument("--log-level", default="INFO", help="Log level")

    # config command
    config_parser = subparsers.add_parser("config", help="Manage configuration")
    config_parser.add_argument("action", nargs="?", default="show", choices=["show", "set", "validate"])
    config_parser.add_argument("--key", help="Config key to set")
    config_parser.add_argument("--value", help="Config value to set")

    args = parser.parse_args()

    if args.command == "list":
        return cmd_list(args)
    elif args.command == "health":
        return cmd_health(args)
    elif args.command == "run":
        return cmd_run(args)
    elif args.command == "config":
        return cmd_config(args)
    else:
        parser.print_help()
        return 0


if __name__ == "__main__":
    sys.exit(main())
