#!/usr/bin/env python3
"""
The Grid CLI - Entry point to the digital frontier.

"The Grid. A digital frontier. I tried to picture clusters of information
as they moved through the computer."

Usage:
    grid                    - Enter The Grid with welcome screen
    grid status             - Show Grid status
    grid build <desc>       - Build something from natural language
    grid --help             - Show help
"""

import sys
import argparse
from pathlib import Path
from typing import Optional

# Add parent to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))

from core.grid import Grid, GridConfig
from core.cluster import Cluster
from core.block import Block
from core.program import Program
from templates.welcome import render_welcome, render_goodbye
from templates.status import render_full_status, render_grid_summary


class GridCLI:
    """
    The Grid CLI - Interactive interface to The Grid.
    """

    def __init__(self, config_path: Optional[Path] = None):
        """Initialize the CLI."""
        self.config_path = config_path or Path(__file__).parent.parent / "config" / "grid.yaml"
        self.grid: Optional[Grid] = None

    def initialize_grid(self) -> Grid:
        """Initialize a new Grid instance."""
        self.grid = Grid(
            name="The Grid",
            config_path=self.config_path if self.config_path.exists() else None,
        )
        return self.grid

    def welcome(self) -> None:
        """Display the welcome screen."""
        print(render_welcome(self.grid))

    def goodbye(self) -> None:
        """Display the goodbye screen."""
        print(render_goodbye())

    def status(self) -> None:
        """Display Grid status."""
        if not self.grid:
            self.initialize_grid()
        print(render_grid_summary(self.grid))

    def full_status(self) -> None:
        """Display full Grid status with all Clusters."""
        if not self.grid:
            self.initialize_grid()
        print(render_full_status(self.grid))

    def parse_intent(self, description: str) -> dict:
        """
        Parse natural language description into Grid structure.

        This is a simplified parser - a full implementation would use
        NLP or an LLM to understand complex requests.

        Returns:
            dict with cluster_name, blocks, and threads
        """
        description = description.lower().strip()

        # Extract key concepts
        structure = {
            "cluster_name": "project",
            "purpose": description,
            "blocks": [],
        }

        # Detect project type and create appropriate structure
        if any(word in description for word in ["api", "rest", "endpoint", "server"]):
            structure["cluster_name"] = "api-project"
            structure["blocks"] = [
                {
                    "name": "design",
                    "purpose": "Design the API architecture",
                    "threads": [
                        {"name": "research", "purpose": "Research patterns and requirements"},
                        {"name": "architecture", "purpose": "Design system architecture"},
                    ],
                },
                {
                    "name": "implement",
                    "purpose": "Implement the API",
                    "blocked_by": ["design"],
                    "threads": [
                        {"name": "models", "purpose": "Create data models"},
                        {"name": "routes", "purpose": "Create API endpoints"},
                        {"name": "middleware", "purpose": "Create middleware"},
                        {"name": "tests", "purpose": "Write tests", "blocked_by": ["models", "routes"]},
                    ],
                },
                {
                    "name": "verify",
                    "purpose": "Verify and validate",
                    "blocked_by": ["implement"],
                    "threads": [
                        {"name": "validate", "purpose": "Run validation", "type": "recognizer"},
                    ],
                },
            ]

        elif any(word in description for word in ["cli", "command", "terminal", "tool"]):
            structure["cluster_name"] = "cli-tool"
            structure["blocks"] = [
                {
                    "name": "design",
                    "purpose": "Design the CLI",
                    "threads": [
                        {"name": "requirements", "purpose": "Define requirements"},
                        {"name": "interface", "purpose": "Design command interface"},
                    ],
                },
                {
                    "name": "implement",
                    "purpose": "Implement the CLI",
                    "blocked_by": ["design"],
                    "threads": [
                        {"name": "parser", "purpose": "Create argument parser"},
                        {"name": "commands", "purpose": "Implement commands"},
                        {"name": "output", "purpose": "Format output"},
                    ],
                },
                {
                    "name": "verify",
                    "purpose": "Test and verify",
                    "blocked_by": ["implement"],
                    "threads": [
                        {"name": "test", "purpose": "Run tests", "type": "recognizer"},
                    ],
                },
            ]

        elif any(word in description for word in ["fix", "bug", "error", "issue"]):
            structure["cluster_name"] = "bugfix"
            structure["blocks"] = [
                {
                    "name": "investigate",
                    "purpose": "Investigate the issue",
                    "threads": [
                        {"name": "reproduce", "purpose": "Reproduce the bug"},
                        {"name": "analyze", "purpose": "Analyze root cause"},
                    ],
                },
                {
                    "name": "fix",
                    "purpose": "Fix the bug",
                    "blocked_by": ["investigate"],
                    "threads": [
                        {"name": "implement", "purpose": "Implement the fix"},
                        {"name": "test", "purpose": "Test the fix"},
                    ],
                },
                {
                    "name": "verify",
                    "purpose": "Verify fix",
                    "blocked_by": ["fix"],
                    "threads": [
                        {"name": "validate", "purpose": "Validate fix", "type": "recognizer"},
                    ],
                },
            ]

        else:
            # Generic project structure
            structure["cluster_name"] = "project"
            structure["blocks"] = [
                {
                    "name": "plan",
                    "purpose": "Plan the work",
                    "threads": [
                        {"name": "analyze", "purpose": "Analyze requirements"},
                        {"name": "design", "purpose": "Design solution"},
                    ],
                },
                {
                    "name": "execute",
                    "purpose": "Execute the work",
                    "blocked_by": ["plan"],
                    "threads": [
                        {"name": "implement", "purpose": "Implement solution"},
                        {"name": "test", "purpose": "Test implementation"},
                    ],
                },
                {
                    "name": "verify",
                    "purpose": "Verify completion",
                    "blocked_by": ["execute"],
                    "threads": [
                        {"name": "validate", "purpose": "Validate work", "type": "recognizer"},
                    ],
                },
            ]

        return structure

    def build_from_structure(self, structure: dict) -> Cluster:
        """Build Grid structure from parsed intent."""
        if not self.grid:
            self.initialize_grid()

        # Create Cluster
        cluster = self.grid.create_cluster(
            name=structure["cluster_name"],
            purpose=structure["purpose"],
        )

        # Create Blocks
        block_map = {}
        for block_def in structure["blocks"]:
            blocked_by = [block_map[name].name for name in block_def.get("blocked_by", []) if name in block_map]

            block = cluster.add_block(
                name=block_def["name"],
                purpose=block_def["purpose"],
                blocked_by=blocked_by,
            )
            block_map[block_def["name"]] = block

            # Create Threads
            thread_map = {}
            for thread_def in block_def.get("threads", []):
                blocked_by_threads = thread_def.get("blocked_by", [])

                thread = block.add_thread(
                    name=thread_def["name"],
                    purpose=thread_def["purpose"],
                    program_type=thread_def.get("type", "program"),
                    blocked_by=blocked_by_threads,
                )
                thread_map[thread_def["name"]] = thread

        # Add I/O Tower checkpoint before commit
        cluster.add_io_checkpoint("Human review required before commit")

        return cluster

    def build(self, description: str) -> None:
        """Build something from natural language description."""
        # Parse intent
        structure = self.parse_intent(description)

        # Build structure
        cluster = self.build_from_structure(structure)

        # Display result
        from templates.status import render_cluster_status
        print()
        print(render_cluster_status(cluster))

    def run_interactive(self) -> None:
        """Run interactive mode."""
        self.initialize_grid()
        self.welcome()

        while True:
            try:
                user_input = input("\n▸ ").strip()

                # Filter out escape sequences (arrow keys, etc.)
                import re
                user_input = re.sub(r'\x1b\[[A-D]', '', user_input)
                user_input = user_input.strip()

                if not user_input:
                    continue

                if user_input.lower() in ("quit", "exit", "q"):
                    self.goodbye()
                    break

                if user_input.lower() == "status":
                    self.full_status()
                    continue

                if user_input.lower() == "energy":
                    from templates.status import render_energy_flow
                    print(render_energy_flow(self.grid))
                    continue

                if user_input.lower() == "help":
                    print("""
Commands:
  status      - Show Grid status
  energy      - Show energy flow
  quit/exit   - Exit The Grid

Or describe what you want to build:
  "a REST API for user authentication"
  "a CLI tool that converts markdown to PDF"
  "fix the bug in my login form"
                    """)
                    continue

                # Treat as build request
                self.build(user_input)

            except KeyboardInterrupt:
                print("\n")
                self.goodbye()
                break

            except EOFError:
                print("\n")
                self.goodbye()
                break


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        description="The Grid - A Digital Frontier",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  grid                              Enter The Grid interactively
  grid status                       Show Grid status
  grid build "a REST API"           Build from description
  grid --config /path/to/grid.yaml  Use custom config

"The Grid. A digital frontier."
        """,
    )

    parser.add_argument(
        "command",
        nargs="?",
        default="interactive",
        choices=["interactive", "status", "build"],
        help="Command to run",
    )

    parser.add_argument(
        "description",
        nargs="?",
        help="Description for build command",
    )

    parser.add_argument(
        "--config",
        type=Path,
        help="Path to config file",
    )

    args = parser.parse_args()

    cli = GridCLI(config_path=args.config)

    if args.command == "status":
        cli.initialize_grid()
        cli.full_status()

    elif args.command == "build":
        if not args.description:
            print("Error: build command requires a description")
            print("Usage: grid build \"description of what to build\"")
            sys.exit(1)
        cli.initialize_grid()
        cli.build(args.description)

    else:
        # Interactive mode
        cli.run_interactive()


if __name__ == "__main__":
    main()
