"""AISA CLI - Agentic AI Systems Architecture Compliance Checker.

Usage:
    aisa check <path>                   Pattern-based scan for AISA compliance
    aisa ai-check <path>                AI-powered deep analysis (requires API key)
    aisa full-check <path>              Combined pattern + AI analysis (best results)
    aisa assess                         Interactive guided assessment questionnaire
"""

import sys
from pathlib import Path

from .scanner.detector import detect_frameworks
from .scanner.analyzer import scan_project
from .assessor.questions import QUESTIONS
from .assessor.scoring import score_responses, VALID_RESPONSES
from .report.generator import print_terminal_report, generate_markdown_report
from .layers import ALL_LAYERS, ALL_CONTRACTS


def main() -> None:
    """Main CLI entry point."""
    args = sys.argv[1:]

    if not args or args[0] in ("-h", "--help", "help"):
        _print_usage()
        return

    command = args[0]

    if command == "check":
        _handle_check(args[1:])
    elif command == "ai-check":
        _handle_ai_check(args[1:])
    elif command == "full-check":
        _handle_full_check(args[1:])
    elif command == "assess":
        _handle_assess(args[1:])
    elif command == "version":
        from . import __version__
        print(f"aisa {__version__}")
    else:
        print(f"Unknown command: {command}")
        _print_usage()
        sys.exit(1)


def _print_usage() -> None:
    print("""
AISA - Agentic AI Systems Architecture Compliance Checker
https://huggingface.co/AISA-Framework

Commands:
    aisa check <path>           Pattern-based scan (fast, no API key needed)
    aisa ai-check <path>        AI-powered deep analysis (requires LLM API key)
    aisa full-check <path>      Combined pattern + AI analysis (best accuracy)
    aisa assess                 Interactive guided assessment questionnaire
    aisa version                Show version

Options:
    --report                    Generate a markdown report file (aisa_report.md)
    --provider <name>           LLM provider: openai, anthropic, google (ai-check/full-check)
    --model <name>              Model name override (ai-check/full-check)
    --api-key <key>             API key for LLM provider (alternative to env vars)

Environment Variables (for ai-check / full-check):
    OPENAI_API_KEY              Use OpenAI models (default: gpt-4o)
    ANTHROPIC_API_KEY           Use Anthropic models (default: claude-sonnet-4-20250514)
    GOOGLE_API_KEY              Use Google models (default: gemini-2.0-flash)

Examples:
    aisa check ./my-agent-project
    aisa check ./my-agent-project --report
    aisa ai-check ./my-agent-project --api-key sk-...
    aisa ai-check ./my-agent-project --provider anthropic --api-key sk-ant-...
    aisa full-check ./my-agent-project --report
    aisa assess --report

Scoring Modes:
    check       Fast pattern matching against 200+ code signatures.
                Good for quick scans. May miss architectural patterns.

    ai-check    Uses an LLM agent to semantically analyze your code.
                Understands architecture, not just keywords.
                Requires an API key (OpenAI, Anthropic, or Google).

    full-check  Runs BOTH pattern scan and AI analysis, then merges
                results. Takes the best score from each method.
                Most accurate but slowest.

    assess      Interactive questionnaire (55 questions). Works for
                any system, even non-Python or proprietary.
""")


def _handle_check(args: list[str]) -> None:
    """Handle the 'check' command - pattern-based scan."""
    if not args:
        print("Error: Please provide a project path.")
        print("Usage: aisa check <path>")
        sys.exit(1)

    project_path = Path(args[0]).resolve()
    generate_report = "--report" in args

    if not project_path.exists():
        print(f"Error: Path does not exist: {project_path}")
        sys.exit(1)

    if not project_path.is_dir():
        print(f"Error: Path is not a directory: {project_path}")
        sys.exit(1)

    print(f"\n  Scanning {project_path}...")
    print("  Mode: Pattern-based scan")
    print("  Detecting frameworks...")

    frameworks = detect_frameworks(project_path)
    if frameworks:
        print(f"  Found: {', '.join(frameworks.keys())}")
    else:
        print("  No known frameworks detected (scanning for general patterns)")

    print("  Analyzing AISA compliance...")
    result = scan_project(project_path, frameworks)

    print_terminal_report(result)

    if generate_report:
        report_path = project_path / "aisa_report.md"
        generate_markdown_report(result, report_path)
        print(f"  Markdown report saved to: {report_path}")


def _handle_ai_check(args: list[str]) -> None:
    """Handle the 'ai-check' command - AI-powered analysis."""
    if not args:
        print("Error: Please provide a project path.")
        print("Usage: aisa ai-check <path>")
        sys.exit(1)

    project_path = Path(args[0]).resolve()
    generate_report = "--report" in args

    if not project_path.exists() or not project_path.is_dir():
        print(f"Error: Invalid directory: {project_path}")
        sys.exit(1)

    config = _parse_ai_config(args)

    print(f"\n  Scanning {project_path}...")
    print("  Mode: AI-powered deep analysis")

    from .ai_checker.agent import ai_check_project

    try:
        result = ai_check_project(project_path, config)
    except RuntimeError as e:
        print(f"\n  Error: {e}")
        sys.exit(1)
    except ImportError as e:
        print(f"\n  Error: {e}")
        sys.exit(1)

    print_terminal_report(result)

    if generate_report:
        report_path = project_path / "aisa_ai_report.md"
        generate_markdown_report(result, report_path)
        print(f"  Markdown report saved to: {report_path}")


def _handle_full_check(args: list[str]) -> None:
    """Handle the 'full-check' command - combined pattern + AI analysis."""
    if not args:
        print("Error: Please provide a project path.")
        print("Usage: aisa full-check <path>")
        sys.exit(1)

    project_path = Path(args[0]).resolve()
    generate_report = "--report" in args

    if not project_path.exists() or not project_path.is_dir():
        print(f"Error: Invalid directory: {project_path}")
        sys.exit(1)

    config = _parse_ai_config(args)

    # Phase 1: Pattern scan
    print(f"\n  Scanning {project_path}...")
    print("  Mode: Full analysis (Pattern + AI)")
    print()
    print("  Phase 1/2: Pattern-based scan...")
    frameworks = detect_frameworks(project_path)
    if frameworks:
        print(f"  Detected: {', '.join(frameworks.keys())}")
    pattern_result = scan_project(project_path, frameworks)
    print(f"  Pattern scan score: {pattern_result.overall_score:.0f}/100")

    # Phase 2: AI analysis
    print()
    print("  Phase 2/2: AI-powered deep analysis...")

    from .ai_checker.agent import ai_check_project
    from .ai_checker.combined import combine_results

    try:
        ai_result = ai_check_project(project_path, config)
        print(f"  AI analysis score: {ai_result.overall_score:.0f}/100")
    except (RuntimeError, ImportError) as e:
        print(f"  AI analysis failed: {e}")
        print("  Falling back to pattern-only results.")
        ai_result = None

    # Phase 3: Combine
    if ai_result:
        print()
        print("  Combining results (best of both methods)...")
        result = combine_results(pattern_result, ai_result)
    else:
        result = pattern_result

    print_terminal_report(result)

    if generate_report:
        report_path = project_path / "aisa_full_report.md"
        generate_markdown_report(result, report_path)
        print(f"  Markdown report saved to: {report_path}")


def _parse_ai_config(args: list[str]):
    """Parse AI-related CLI arguments into an AICheckConfig."""
    from .ai_checker.agent import AICheckConfig

    provider = ""
    model = ""
    api_key = ""

    for i, arg in enumerate(args):
        if arg == "--provider" and i + 1 < len(args):
            provider = args[i + 1]
        elif arg == "--model" and i + 1 < len(args):
            model = args[i + 1]
        elif arg == "--api-key" and i + 1 < len(args):
            api_key = args[i + 1]

    return AICheckConfig(provider=provider or "openai", model=model, api_key=api_key)


def _handle_assess(args: list[str]) -> None:
    """Handle the 'assess' command - interactive questionnaire."""
    generate_report = "--report" in args

    print()
    print("=" * 60)
    print("  AISA GUIDED ASSESSMENT")
    print("  Answer each question with: yes / partial / no / na")
    print("  (Press Ctrl+C to cancel)")
    print("=" * 60)

    project_name = input("\n  Project name: ").strip() or "Unnamed Project"
    responses: dict[str, str] = {}

    all_components = [(l.id, l.name) for l in ALL_LAYERS] + [(c.id, c.name) for c in ALL_CONTRACTS]

    try:
        for component_id, component_name in all_components:
            questions = QUESTIONS.get(component_id, [])
            if not questions:
                continue

            print(f"\n  --- {component_id}: {component_name} ---")
            print()

            for q in questions:
                while True:
                    prompt = f"  {q.criterion_id}: {q.text}\n"
                    if q.help_text:
                        prompt += f"         ({q.help_text})\n"
                    prompt += "         [yes/partial/no/na]: "

                    try:
                        answer = input(prompt).strip().lower()
                    except EOFError:
                        answer = "no"

                    if answer in ("y", "yes"):
                        answer = "yes"
                    elif answer in ("p", "partial"):
                        answer = "partial"
                    elif answer in ("n", "no", ""):
                        answer = "no"
                    elif answer in ("na", "n/a", "skip"):
                        answer = "na"
                    else:
                        print("         Please enter: yes, partial, no, or na")
                        continue

                    responses[q.criterion_id] = answer
                    break

    except KeyboardInterrupt:
        print("\n\n  Assessment cancelled. Generating partial report...\n")

    result = score_responses(responses, project_name)
    print_terminal_report(result)

    if generate_report:
        report_path = Path.cwd() / "aisa_report.md"
        generate_markdown_report(result, report_path)
        print(f"  Markdown report saved to: {report_path}")


if __name__ == "__main__":
    main()
