"""Entry point for the application.

Provides a CLI REPL for building geometric models.
"""

import re
import sys
from geometor.model import Model
from geometor.model.sections import Section
from rich.console import Console
from rich.panel import Panel

console = Console()

def parse_command(model: Model, command: str) -> None:
    """Parses and executes a single command string."""
    command = command.strip()
    if not command:
        return

    # Point: A = 0, 0
    point_match = re.match(r"^([A-Za-z0-9_]+)\s*=\s*([-\d\.]+)\s*,\s*([-\d\.]+)(?:\s+(.*))?$", command)
    if point_match:
        label, x, y, remainder = point_match.groups()
        try:
            pt = model.set_point(float(x), float(y), ID=label, classes=["given"])
            return
        except Exception as e:
            console.print(f"[red]Error creating point:[/red] {e}")
            return

    # Auto-Label Point: * 0, 0
    auto_point_match = re.match(r"^\*\s*([-\d\.]+)\s*,\s*([-\d\.]+)(?:\s+(.*))?$", command)
    if auto_point_match:
        x, y, remainder = auto_point_match.groups()
        try:
            # ID is not passed, so it will be auto-generated by the model
            pt = model.set_point(float(x), float(y), classes=["given"])
            return
        except Exception as e:
            console.print(f"[red]Error creating point:[/red] {e}")
            return


    # Line: [ A B ]
    line_match = re.match(r"^\[\s*([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+)\s*\]$", command)
    if line_match:
        pt1, pt2 = line_match.groups()
        try:
            line = model.construct_line_by_IDs(pt1, pt2)
            return
        except Exception as e:
            console.print(f"[red]Error creating line:[/red] {e}")
            return

    # Circle: ( A B )
    circle_match = re.match(r"^\(\s*([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+)\s*\)$", command)
    if circle_match:
        pt1, pt2 = circle_match.groups()
        try:
            circle = model.construct_circle_by_IDs(pt1, pt2)
            return
        except Exception as e:
            console.print(f"[red]Error creating circle:[/red] {e}")
            return

    # Polygon: < A B C >
    if match := re.match(r"^<\s*([A-Za-z0-9\s]+?)\s*>$", command):
        pts = match.group(1).split()
        if len(pts) >= 3:
            try:
                model.set_polygon_by_IDs(pts)
            except Exception as e:
                print(f"Error creating polygon: {e}")
        else:
            print("Polygon requires at least 3 points")
        return

    # Linear Division: / A B ... /
    if match := re.match(r"^/\s*([A-Za-z0-9\s]+?)\s*/$", command):
        pts = match.group(1).split()
        if len(pts) == 2:
            # Segment
            try:
                model.set_segment_by_IDs(pts[0], pts[1])
            except Exception as e:
                print(f"Error creating segment: {e}")
        elif len(pts) == 3:
            # Section
            try:
                model.set_section_by_IDs(pts)
            except Exception as e:
                print(f"Error creating section: {e}")
        else:
            print("Linear division requires 2 or 3 points (Segment or Section)")
        return

    # Wedge: < A B E )
    if match := re.match(r"^<\s*([A-Za-z0-9\s]+?)\s*\)$", command):
        pts = match.group(1).split()
        if len(pts) == 3:
            # Center: pts[0], Radius: pts[1], Sweep End: pts[2]
            # Sweep Start implicitly Radius point (pts[1])
            try:
                model.set_wedge_by_IDs(pts[0], pts[1], pts[1], pts[2])
            except Exception as e:
                print(f"Error creating wedge: {e}")
        else:
            print("Wedge requires 3 points: < Center Radius SweepEnd )")
        return 
    console.print(f"[yellow]Unknown command:[/yellow] {command}")


def run() -> None:
    """Runs the CLI REPL."""
    model = Model("cli_model")
    console.print("[bold green]Geometor CLI[/bold green]")
    console.print("Commands:")
    console.print("  [cyan]LABEL = x, y[/cyan]   : Create a point (e.g., A = 0, 0)")
    console.print("  [cyan]* x, y[/cyan]       : Create a point with auto-generated label")
    console.print("  [cyan][ A B ][/cyan]         : Create a line connecting points A and B")
    console.print("  [cyan]( A B )[/cyan]         : Create a circle with center A and radius point B")
    console.print("  [cyan]< A B C >[/cyan]       : Create a polygon (3+ points)")
    console.print("  [cyan]/ A B /[/cyan]         : Create a segment from A to B")
    console.print("  [cyan]} A B C {[/cyan]       : Create a section (3 collinear points)")
    console.print("  [cyan]^ A B C D ^[/cyan]     : Create a wedge (Center A, Radius B, Sweep Start C, Sweep End D)")
    console.print("  [cyan]exit[/cyan] / [cyan]quit[/cyan]    : Exit the program")
    console.print()

    while True:
        try:
            command = console.input("[bold blue]>[/bold blue] ")
            if command.lower() in ("exit", "quit"):
                break
            parse_command(model, command)
        except (KeyboardInterrupt, EOFError):
            console.print("\n[yellow]Exiting...[/yellow]")
            break
        except Exception as e:
            console.print(f"[red]Unexpected error:[/red] {e}")

if __name__ == "__main__":
    run()
