"""
CLI interface for system-sage
"""

import argparse
import sys

from .detector import detect_system, get_system_facts, print_system_info
from .reasoner import PrologEngine, fact, var
from .knowledge import build_knowledge_base, TASKS
from .optimizer import (
    list_tasks, get_recommendations, optimize_for,
    print_recommendations, get_suitability
)


def cmd_info(args):
    """Show system information"""
    print_system_info()

    if args.facts:
        print("\nProlog Facts:")
        print("-" * 40)
        for f in get_system_facts():
            if len(f) == 2:
                print(f"  {f[0]}({f[1]}).")
            else:
                args_str = ", ".join(str(a) for a in f[1:])
                print(f"  {f[0]}({args_str}).")


def cmd_list(args):
    """List available optimization tasks"""
    tasks = list_tasks()

    print("\nAvailable Optimization Tasks:")
    print("=" * 50)

    for name, description in sorted(tasks.items()):
        suitability = get_suitability(name)
        rating = suitability[1] if suitability else "?"

        # Color coding (simple ASCII indicators)
        if rating == "excellent":
            indicator = "[+++]"
        elif rating == "good":
            indicator = "[++ ]"
        elif rating == "limited" or rating == "cpu_only":
            indicator = "[+  ]"
        else:
            indicator = "[   ]"

        print(f"  {indicator} {name:20} - {description}")

    print("\n  Legend: [+++] Excellent  [++ ] Good  [+  ] Limited  [   ] Unknown")
    print("\nUse 'system-sage optimize <task>' for recommendations")


def cmd_optimize(args):
    """Get optimization recommendations for a task"""
    task = args.task.lower().replace(" ", "_").replace("-", "_")

    if task not in TASKS:
        print(f"Error: Unknown task '{args.task}'")
        print(f"Use 'system-sage list' to see available tasks")
        sys.exit(1)

    recommendations = optimize_for(task, dry_run=not args.apply)
    print_recommendations(recommendations)

    if not args.apply and recommendations["optimizations"]:
        print("\nTo apply these optimizations, run:")
        print(f"  system-sage optimize {task} --apply")
        print("\n(Some optimizations may require admin/root privileges)")


def cmd_check(args):
    """Check system suitability for a task"""
    task = args.task.lower().replace(" ", "_").replace("-", "_")

    if task not in TASKS:
        print(f"Error: Unknown task '{args.task}'")
        sys.exit(1)

    recommendations = get_recommendations(task)

    print(f"\nSuitability Check: {task.upper()}")
    print("=" * 40)
    print(f"Description: {recommendations['task_description']}")
    print()

    # System summary
    print("Your System:")
    for key, value in recommendations["system_summary"].items():
        print(f"  {key}: {value}")

    print()

    # Rating
    if recommendations["suitability"]:
        rating = recommendations["suitability"]
        if rating == "excellent":
            print(f"Rating: EXCELLENT - Your system is well-suited for {task}")
        elif rating == "good":
            print(f"Rating: GOOD - Your system can handle {task} well")
        elif rating == "limited":
            print(f"Rating: LIMITED - {task} will work but with reduced performance")
        elif rating == "cpu_only":
            print(f"Rating: CPU ONLY - GPU acceleration not available")
        else:
            print(f"Rating: {rating.upper()}")
    else:
        print("Rating: UNKNOWN - No suitability rules matched")

    # Warnings
    if recommendations["warnings"]:
        print("\nWarnings:")
        for warn in recommendations["warnings"]:
            print(f"  ⚠ {warn['message']}")

    # Requirements from task definition
    task_info = TASKS.get(task, {})
    if task_info.get("requirements"):
        print("\nTask Requirements:")
        for req, val in task_info["requirements"].items():
            print(f"  - {req}: {val}")


def cmd_query(args):
    """Run a custom Prolog query"""
    engine = PrologEngine()
    system_facts = get_system_facts()
    build_knowledge_base(engine, system_facts)

    # Parse the query
    query_str = args.query

    # Simple parsing for predicate(arg1, arg2, ...)
    import re
    match = re.match(r'(\w+)\s*\((.*)\)', query_str)

    if not match:
        print(f"Error: Invalid query format. Use: predicate(arg1, arg2, ...)")
        print(f"Example: suitable_for(gaming, X)")
        sys.exit(1)

    predicate = match.group(1)
    args_str = match.group(2)

    # Parse arguments
    query_args = []
    for arg in args_str.split(","):
        arg = arg.strip()
        if not arg:
            continue
        if arg[0].isupper() or arg == "_":
            query_args.append(var(arg))
        elif arg.isdigit():
            query_args.append(int(arg))
        elif arg.replace(".", "").isdigit():
            query_args.append(float(arg))
        elif arg.startswith('"') and arg.endswith('"'):
            query_args.append(arg[1:-1])
        else:
            query_args.append(arg)

    goal = fact(predicate, *query_args)
    print(f"\nQuery: {goal}")
    print("-" * 40)

    solutions = engine.query_all(goal)

    if solutions:
        print(f"Found {len(solutions)} solution(s):\n")
        for i, sol in enumerate(solutions, 1):
            if sol:
                bindings = ", ".join(f"{k} = {v}" for k, v in sol.items() if not k.startswith("_"))
                if bindings:
                    print(f"  {i}. {bindings}")
                else:
                    print(f"  {i}. true")
            else:
                print(f"  {i}. true")
    else:
        print("No solutions found (false)")


def cmd_explain(args):
    """Explain the reasoning for a task's recommendations"""
    task = args.task.lower().replace(" ", "_").replace("-", "_")

    if task not in TASKS:
        print(f"Error: Unknown task '{args.task}'")
        sys.exit(1)

    engine = PrologEngine()
    system_facts = get_system_facts()
    build_knowledge_base(engine, system_facts)

    print(f"\nReasoning Explanation: {task.upper()}")
    print("=" * 50)

    print("\n1. System Facts (detected from your system):")
    print("-" * 40)
    for f in system_facts:
        if len(f) == 2:
            print(f"   {f[0]}({f[1]})")
        else:
            args_str = ", ".join(str(a) for a in f[1:])
            print(f"   {f[0]}({args_str})")

    print(f"\n2. Suitability Query: suitable_for({task}, Rating)?")
    print("-" * 40)

    Rating = var("Rating")
    solutions = engine.query_all(fact("suitable_for", task, Rating))

    if solutions:
        for sol in solutions:
            print(f"   → Rating = {sol.get('Rating')}")
    else:
        print("   → No matching suitability rules")

    print(f"\n3. Optimization Query: optimize({task}, Setting, Value)?")
    print("-" * 40)

    Setting = var("Setting")
    Value = var("Value")
    opt_solutions = engine.query_all(fact("optimize", task, Setting, Value))

    if opt_solutions:
        seen = set()
        for sol in opt_solutions:
            key = (sol.get("Setting"), sol.get("Value"))
            if key not in seen:
                seen.add(key)
                print(f"   → {sol.get('Setting')} = {sol.get('Value')}")
    else:
        print("   → No matching optimization rules")

    print(f"\n4. Warning Query: warning({task}, Type, Message)?")
    print("-" * 40)

    WarnType = var("Type")
    Message = var("Message")
    warn_solutions = engine.query_all(fact("warning", task, WarnType, Message))

    if warn_solutions:
        seen = set()
        for sol in warn_solutions:
            msg = sol.get("Message")
            if msg and msg not in seen:
                seen.add(msg)
                print(f"   → {sol.get('Type')}: {msg}")
    else:
        print("   → No warnings")

    print()


def cmd_interactive(args):
    """Interactive mode"""
    engine = PrologEngine()
    system_facts = get_system_facts()
    build_knowledge_base(engine, system_facts)

    print("\nsystem-sage interactive mode")
    print("Commands: list, info, optimize <task>, check <task>, query <prolog>, explain <task>, quit")
    print("-" * 60)

    while True:
        try:
            line = input("\nsage> ").strip()
        except (EOFError, KeyboardInterrupt):
            print("\nGoodbye!")
            break

        if not line:
            continue

        parts = line.split(maxsplit=1)
        cmd = parts[0].lower()
        arg = parts[1] if len(parts) > 1 else ""

        if cmd in ("quit", "exit", "q"):
            print("Goodbye!")
            break
        elif cmd == "list":
            cmd_list(argparse.Namespace())
        elif cmd == "info":
            cmd_info(argparse.Namespace(facts=True))
        elif cmd == "optimize":
            if arg:
                cmd_optimize(argparse.Namespace(task=arg, apply=False))
            else:
                print("Usage: optimize <task>")
        elif cmd == "check":
            if arg:
                cmd_check(argparse.Namespace(task=arg))
            else:
                print("Usage: check <task>")
        elif cmd == "query":
            if arg:
                cmd_query(argparse.Namespace(query=arg))
            else:
                print("Usage: query <prolog_query>")
                print("Example: query suitable_for(gaming, X)")
        elif cmd == "explain":
            if arg:
                cmd_explain(argparse.Namespace(task=arg))
            else:
                print("Usage: explain <task>")
        elif cmd == "help":
            print("Commands:")
            print("  list              - List available tasks")
            print("  info              - Show system information")
            print("  optimize <task>   - Get optimization recommendations")
            print("  check <task>      - Check suitability for a task")
            print("  query <prolog>    - Run a Prolog query")
            print("  explain <task>    - Explain reasoning for a task")
            print("  quit              - Exit")
        else:
            print(f"Unknown command: {cmd}")
            print("Type 'help' for available commands")


def main():
    parser = argparse.ArgumentParser(
        prog="system-sage",
        description="Prolog-powered system optimizer - uses logical reasoning to optimize your system"
    )

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

    # Info command
    info_parser = subparsers.add_parser("info", help="Show system information")
    info_parser.add_argument("--facts", "-f", action="store_true",
                            help="Show Prolog facts")

    # List command
    list_parser = subparsers.add_parser("list", help="List available optimization tasks")

    # Optimize command
    opt_parser = subparsers.add_parser("optimize", help="Get optimization recommendations")
    opt_parser.add_argument("task", help="Task to optimize for (e.g., gaming, video_editing)")
    opt_parser.add_argument("--apply", "-a", action="store_true",
                           help="Actually apply optimizations (default is dry-run)")

    # Check command
    check_parser = subparsers.add_parser("check", help="Check system suitability for a task")
    check_parser.add_argument("task", help="Task to check suitability for")

    # Query command
    query_parser = subparsers.add_parser("query", help="Run a custom Prolog query")
    query_parser.add_argument("query", help="Prolog query (e.g., 'suitable_for(gaming, X)')")

    # Explain command
    explain_parser = subparsers.add_parser("explain", help="Explain reasoning for a task")
    explain_parser.add_argument("task", help="Task to explain")

    # Interactive command
    interactive_parser = subparsers.add_parser("interactive", aliases=["i"],
                                               help="Interactive mode")

    args = parser.parse_args()

    if args.command == "info":
        cmd_info(args)
    elif args.command == "list":
        cmd_list(args)
    elif args.command == "optimize":
        cmd_optimize(args)
    elif args.command == "check":
        cmd_check(args)
    elif args.command == "query":
        cmd_query(args)
    elif args.command == "explain":
        cmd_explain(args)
    elif args.command in ("interactive", "i"):
        cmd_interactive(args)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()
