"""
CLI interface for query paradigm discovery and interaction.
"""

import argparse
import json
import sys
from typing import Dict, Any

from .registry import registry


def list_paradigms():
    """List all available query paradigms."""
    paradigms = registry.list_all()

    print(f"📚 MarkiTect Query Paradigms ({len(paradigms)} available)")
    print("=" * 50)

    # Group by category
    categories = {}
    for paradigm in paradigms:
        if paradigm.category not in categories:
            categories[paradigm.category] = []
        categories[paradigm.category].append(paradigm)

    for category, paradigm_list in categories.items():
        print(f"\n🏷️  {category.upper()} PARADIGMS")
        print("-" * 30)

        for paradigm in paradigm_list:
            status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"
            print(f"  {status} {paradigm.name} ({paradigm.complexity})")
            print(f"    {paradigm.description}")
            print()


def show_paradigm_details(name: str):
    """Show detailed information about a specific paradigm."""
    paradigm = registry.get(name)

    if not paradigm:
        print(f"❌ Paradigm '{name}' not found.")
        print("\nAvailable paradigms:")
        for p in registry.list_all():
            print(f"  - {p.name}")
        return

    status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"

    print(f"🔍 {paradigm.name} Query Paradigm")
    print("=" * (len(paradigm.name) + 20))
    print(f"Status: {status}")
    print(f"Category: {paradigm.category}")
    print(f"Complexity: {paradigm.complexity}")
    print(f"Description: {paradigm.description}")
    print()

    print("📝 Syntax Help:")
    print("-" * 15)
    print(paradigm.get_syntax_help())
    print()

    print("💡 Examples:")
    print("-" * 12)
    examples = paradigm.get_examples()
    for i, example in enumerate(examples, 1):
        print(f"{i}. {example['name']}")
        print(f"   {example['description']}")
        print(f"   Query: {example['query']}")
        print()


def search_paradigms(query: str):
    """Search paradigms by name or description."""
    results = registry.search_paradigms(query)

    if not results:
        print(f"❌ No paradigms found matching '{query}'")
        return

    print(f"🔍 Search results for '{query}' ({len(results)} found)")
    print("=" * 40)

    for paradigm in results:
        status = "✅ IMPLEMENTED" if paradigm.name in ['SQL', 'FTS', 'GraphQL', 'JSONPath', 'Natural Language'] else "📋 DOCUMENTED"
        print(f"  {status} {paradigm.name} ({paradigm.category}, {paradigm.complexity})")
        print(f"    {paradigm.description}")
        print()


def execute_query(paradigm_name: str, query: str, config_str: str = None):
    """Execute a query using specified paradigm."""
    paradigm = registry.get(paradigm_name)

    if not paradigm:
        print(f"❌ Paradigm '{paradigm_name}' not found.")
        return

    # Parse config if provided
    config = {}
    if config_str:
        try:
            config = json.loads(config_str)
        except json.JSONDecodeError:
            print("❌ Invalid JSON in config parameter")
            return

    # Validate query first
    valid, error = paradigm.validate_query(query)
    if not valid:
        print(f"❌ Invalid query: {error}")
        return

    print(f"🚀 Executing {paradigm.name} query...")
    print(f"Query: {query}")
    if config:
        print(f"Config: {config}")
    print()

    try:
        result = paradigm.execute(query, config)

        print(f"⏱️  Execution time: {result.execution_time_ms:.2f}ms")
        print(f"📊 Result count: {result.result_count}")
        print(f"✅ Success: {result.success}")

        if result.error_message:
            print(f"❌ Error: {result.error_message}")

        if result.metadata:
            print("\n📋 Metadata:")
            for key, value in result.metadata.items():
                print(f"  {key}: {value}")

        if result.results:
            print(f"\n📄 Results:")
            for i, row in enumerate(result.results[:5], 1):  # Show first 5 results
                print(f"  {i}. {row}")

            if len(result.results) > 5:
                print(f"  ... and {len(result.results) - 5} more results")

    except Exception as e:
        print(f"❌ Execution error: {e}")


def list_categories():
    """List all available categories."""
    categories = registry.get_categories()
    print("📂 Available Categories:")
    for category in sorted(categories):
        paradigms = registry.list_by_category(category)
        print(f"  {category}: {len(paradigms)} paradigms")


def show_translation_matrix():
    """Show paradigm translation capabilities."""
    matrix = registry.get_translation_matrix()

    print("🔄 Paradigm Translation Matrix")
    print("=" * 30)
    print("(Which paradigms can translate to which others)")
    print()

    for source, targets in matrix.items():
        if targets:
            print(f"{source} → {', '.join(targets)}")
        else:
            print(f"{source} → (no translations available)")


def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        description="MarkiTect Query Paradigm Explorer",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  %(prog)s list                           # List all paradigms
  %(prog)s search "semantic"              # Search paradigms
  %(prog)s show "Natural Language"        # Show paradigm details
  %(prog)s exec FTS "documentation"       # Execute query
  %(prog)s categories                     # List categories
  %(prog)s translations                   # Show translation matrix
        """
    )

    subparsers = parser.add_subparsers(dest='command', help='Available commands')

    # List command
    subparsers.add_parser('list', help='List all available paradigms')

    # Search command
    search_parser = subparsers.add_parser('search', help='Search paradigms')
    search_parser.add_argument('query', help='Search query')

    # Show command
    show_parser = subparsers.add_parser('show', help='Show paradigm details')
    show_parser.add_argument('name', help='Paradigm name')

    # Execute command
    exec_parser = subparsers.add_parser('exec', help='Execute query')
    exec_parser.add_argument('paradigm', help='Paradigm name')
    exec_parser.add_argument('query', help='Query to execute')
    exec_parser.add_argument('--config', help='JSON configuration')

    # Categories command
    subparsers.add_parser('categories', help='List categories')

    # Translations command
    subparsers.add_parser('translations', help='Show translation matrix')

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        return

    try:
        if args.command == 'list':
            list_paradigms()
        elif args.command == 'search':
            search_paradigms(args.query)
        elif args.command == 'show':
            show_paradigm_details(args.name)
        elif args.command == 'exec':
            execute_query(args.paradigm, args.query, args.config)
        elif args.command == 'categories':
            list_categories()
        elif args.command == 'translations':
            show_translation_matrix()
    except KeyboardInterrupt:
        print("\n👋 Goodbye!")
        sys.exit(0)
    except Exception as e:
        print(f"❌ Error: {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()