#!/usr/bin/env python3
"""
TOXO Command Line Interface

Provides command-line tools for working with .toxo files.
"""

import sys
import argparse
import os
import subprocess
from pathlib import Path
from typing import Optional, List, Dict, Tuple

from .utils import (
    get_version, 
    check_dependencies, 
    print_dependency_status,
    validate_toxo_file,
    print_toxo_info,
    get_sample_usage,
    get_help_text
)


def cmd_version():
    """Print version information."""
    print(f"🧠 TOXO v{get_version()}")
    print("Smart Layer for Context Augmented Language Models (CALM)")
    print("https://toxotune.com")


def cmd_check():
    """Check dependencies and system status."""
    print("🔍 TOXO CALM Layer Dependency Check")
    print("=" * 40)
    deps = check_dependencies()
    print(f"Python Version: {deps.get('python_version')}")
    print(f"Status: {deps.get('status')}")
    print("")
    print("Required packages:")
    for pkg, status in deps.get("required_packages", {}).items():
        print(f"  - {pkg}: {status}")
    print("")
    print("Optional packages:")
    for pkg, status in deps.get("optional_packages", {}).items():
        print(f"  - {pkg}: {status}")


def cmd_info(file_path: str):
    """Show information about a .toxo file."""
    if not file_path:
        print("❌ Error: Please specify a .toxo file path")
        return
    
    print_toxo_info(file_path)


def cmd_validate(file_path: str):
    """Validate a .toxo file."""
    if not file_path:
        print("❌ Error: Please specify a .toxo file path")
        return
    
    result = validate_toxo_file(file_path)
    
    if result["valid"]:
        print(f"✅ {Path(file_path).name} is a valid TOXO file")
        if result["warnings"]:
            print("\n⚠️ Warnings:")
            for warning in result["warnings"]:
                print(f"  • {warning}")
    else:
        print(f"❌ {Path(file_path).name} is not a valid TOXO file")
        print("\n🚫 Errors:")
        for error in result["errors"]:
            print(f"  • {error}")


def cmd_sample():
    """Print sample usage code."""
    print("📖 TOXO Sample Usage Code:")
    print("=" * 40)
    print(get_sample_usage())


def cmd_help():
    """Print help information."""
    print(get_help_text())


def cmd_test(file_path: str, api_key: Optional[str] = None):
    """Test a .toxo file with a sample query."""
    if not file_path:
        print("❌ Error: Please specify a .toxo file path")
        return
    
    api_key = api_key or os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
    if not api_key:
        print("❌ Error: No API key configured.")
        print("   Provide --api-key or set GEMINI_API_KEY / GOOGLE_API_KEY in your environment.")
        return
    
    try:
        from .core import ToxoLayer
        
        print(f"🧪 Testing {Path(file_path).name}...")
        
        # Load the model
        layer = ToxoLayer.load(file_path)
        print("✅ Model loaded successfully")
        
        # Setup API key
        layer.setup_api_key(api_key)
        print("✅ API key configured")
        
        # Get model info
        info = layer.get_info()
        print(f"📊 Model: {info['name']} (Domain: {info['domain']})")
        
        # Test query
        test_question = f"What can you tell me about {info['domain']}?"
        print(f"❓ Test question: {test_question}")
        
        import asyncio
        response = asyncio.run(layer.query(test_question))
        print(f"💬 Response: {response[:200]}{'...' if len(response) > 200 else ''}")
        
        print("🎉 Test completed successfully!")
        
    except Exception as e:
        print(f"❌ Test failed: {str(e)}")


_USECASES: Dict[str, Dict[str, object]] = {
    "vision": {
        "label": "Multimodal PDFs/images (Gemini)",
        "extras": ["vision"],
        "system": {
            "darwin": ["brew install poppler  # required for pdf2image"],
        },
    },
    "rag": {
        "label": "RAG / vector store / retrieval",
        "extras": ["rag"],
        "system": {},
    },
    "enterprise": {
        "label": "Monitoring / caching (enterprise)",
        "extras": ["enterprise"],
        "system": {},
    },
    "distributed": {
        "label": "Distributed (Redis-backed features)",
        "extras": ["distributed"],
        "system": {},
    },
    "auth": {
        "label": "Auth/JWT (server-style features)",
        "extras": ["auth"],
        "system": {},
    },
    "payments": {
        "label": "Payments/subscriptions (Razorpay)",
        "extras": ["payments"],
        "system": {},
    },
    "full": {
        "label": "Everything (largest install)",
        "extras": ["full"],
        "system": {
            "darwin": ["brew install poppler  # for pdf2image"],
        },
    },
}


def _repo_root() -> Optional[Path]:
    # If running from a source checkout, toxo/cli.py is inside the repo.
    try:
        here = Path(__file__).resolve()
        root = here.parents[1]
        if (root / "pyproject.toml").exists():
            return root
    except Exception:
        pass
    return None


def _pip_install(*, extras: List[str], run: bool) -> Tuple[str, List[str]]:
    """
    Returns (install_cmd_str, errors).
    """
    extras_str = ",".join(extras)
    root = _repo_root()
    if root:
        cmd = [sys.executable, "-m", "pip", "install", "-e", f".[{extras_str}]"]
        cmd_str = " ".join(cmd)
        if not run:
            return cmd_str, []
        p = subprocess.run(cmd, cwd=str(root), capture_output=True, text=True)
        if p.returncode != 0:
            return cmd_str, [p.stderr.strip() or p.stdout.strip() or "pip failed"]
        return cmd_str, []

    # Installed package environment.
    cmd = [sys.executable, "-m", "pip", "install", f"toxo[{extras_str}]"]
    cmd_str = " ".join(cmd)
    if not run:
        return cmd_str, []
    p = subprocess.run(cmd, capture_output=True, text=True)
    if p.returncode != 0:
        return cmd_str, [p.stderr.strip() or p.stdout.strip() or "pip failed"]
    return cmd_str, []


def cmd_install(usecase: Optional[str], *, run: bool = False):
    """
    Interactive dependency install helper (use-case based).

    NOTE: pip cannot prompt during installation; this is a post-install wizard.
    """
    if not usecase:
        print("🧩 Choose a TOXO use case to install:")
        keys = list(_USECASES.keys())
        for i, k in enumerate(keys, start=1):
            print(f"  {i}. {k:11} - {_USECASES[k]['label']}")
        try:
            raw = input("Enter number (or a usecase key): ").strip()
        except EOFError:
            raw = ""
        if raw.isdigit():
            idx = int(raw)
            if 1 <= idx <= len(keys):
                usecase = keys[idx - 1]
        else:
            usecase = raw or None

    if not usecase or usecase not in _USECASES:
        print("❌ Unknown use case.")
        print("   Valid:", ", ".join(_USECASES.keys()))
        return

    spec = _USECASES[usecase]
    extras = spec["extras"]  # type: ignore[assignment]
    cmd_str, errors = _pip_install(extras=extras, run=run)

    print(f"✅ Use case: {usecase} - {spec['label']}")
    print(f"📦 Python deps: `{cmd_str}`" if not run else f"📦 Installed via: `{cmd_str}`")

    sys_lines: List[str] = []
    system_map = spec.get("system", {})  # type: ignore[assignment]
    if isinstance(system_map, dict):
        if sys.platform.startswith("darwin"):
            sys_lines = system_map.get("darwin", [])  # type: ignore[assignment]
        elif sys.platform.startswith("linux"):
            sys_lines = system_map.get("linux", [])  # type: ignore[assignment]
        elif sys.platform.startswith("win"):
            sys_lines = system_map.get("win32", [])  # type: ignore[assignment]
    if sys_lines:
        print("🔧 System deps:")
        for line in sys_lines:
            print(f"   - {line}")

    if errors:
        print("❌ Install failed:")
        for e in errors:
            print(f"   - {e}")


def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="toxo",
        description="TOXO - Smart Layer for Context Augmented Language Models (CALM) CLI",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  toxo version                    # Show version
  toxo check                      # Check dependencies  
  toxo info model.toxo            # Show model info
  toxo validate model.toxo        # Validate model file
  toxo test model.toxo --api-key KEY  # Test model (or set GEMINI_API_KEY)
  toxo sample                     # Show sample code
  toxo help                       # Show help

Visit https://toxotune.com to create your AI experts!
        """
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Available commands")
    
    # Version command
    subparsers.add_parser("version", help="Show version information")
    
    # Check command  
    subparsers.add_parser("check", help="Check dependencies and system status")
    
    # Info command
    info_parser = subparsers.add_parser("info", help="Show information about a .toxo file")
    info_parser.add_argument("file", help="Path to .toxo file")
    
    # Validate command
    validate_parser = subparsers.add_parser("validate", help="Validate a .toxo file")
    validate_parser.add_argument("file", help="Path to .toxo file")
    
    # Test command
    test_parser = subparsers.add_parser("test", help="Test a .toxo file")
    test_parser.add_argument("file", help="Path to .toxo file")
    test_parser.add_argument("--api-key", required=False, help="API key for testing (or set GEMINI_API_KEY)")

    # Install command (dependency wizard)
    install_parser = subparsers.add_parser("install", help="Install optional deps by use case")
    install_parser.add_argument("usecase", nargs="?", help=f"One of: {', '.join(_USECASES.keys())}")
    install_parser.add_argument("--run", action="store_true", help="Actually run pip install (default: just print commands)")
    
    # Sample command
    subparsers.add_parser("sample", help="Show sample usage code")
    
    # Help command
    subparsers.add_parser("help", help="Show detailed help information")
    
    # Parse arguments
    args = parser.parse_args()
    
    # Handle commands
    if args.command == "version":
        cmd_version()
    elif args.command == "check":
        cmd_check()
    elif args.command == "info":
        cmd_info(args.file)
    elif args.command == "validate":
        cmd_validate(args.file)
    elif args.command == "test":
        cmd_test(args.file, getattr(args, "api_key", None))
    elif args.command == "install":
        cmd_install(getattr(args, "usecase", None), run=getattr(args, "run", False))
    elif args.command == "sample":
        cmd_sample()
    elif args.command == "help":
        cmd_help()
    else:
        # Show help if no command specified
        parser.print_help()


if __name__ == "__main__":
    main()
