"""FastMCP server with turtle drawing tool registrations."""

from typing import Annotated

from mcp.server.fastmcp import FastMCP
from pydantic import Field

from turtle_mcp.utils import execute_drawing
from turtle_mcp.drawings.geometric import (
    draw_star, draw_spiral, draw_mandala, draw_rosette, draw_polygon_grid,
)
from turtle_mcp.drawings.fractals import (
    draw_fractal_tree, draw_koch_snowflake, draw_sierpinski, draw_dragon_curve,
)
from turtle_mcp.drawings.nature import (
    draw_flower, draw_landscape, draw_sun_moon, draw_house, draw_bouquet,
)

mcp = FastMCP("turtle_mcp")

# ── Geometric tools ────────────────────────────────────────────────────────

@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_star(
    points: Annotated[int, Field(default=5, description="Number of star points", ge=3, le=36)],
    size: Annotated[float, Field(default=200.0, description="Size of the star in pixels", ge=20, le=500)],
    fill_color: Annotated[str | None, Field(default=None, description="Fill color (hex like '#FF0000' or name)")] = None,
    palette: Annotated[str | None, Field(default=None, description="Color palette: rainbow, sunset, ocean, forest, pastel, jewel, autumn, cherry, earth, neon")] = None,
) -> str:
    """Draw a beautiful multi-pointed star with optional fill color and palette."""
    return await execute_drawing(
        lambda t, s: draw_star(t, s, points=points, size=size, fill_color=fill_color, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_spiral(
    spiral_type: Annotated[str, Field(default="archimedean", description="Spiral type: archimedean, logarithmic, or fibonacci")],
    turns: Annotated[int, Field(default=10, description="Number of turns/iterations", ge=1, le=30)],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a mesmerising spiral — Archimedean, logarithmic, or Fibonacci."""
    return await execute_drawing(
        lambda t, s: draw_spiral(t, s, spiral_type=spiral_type, turns=turns, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_mandala(
    layers: Annotated[int, Field(default=6, description="Number of concentric layers", ge=2, le=12)],
    symmetry: Annotated[int, Field(default=8, description="Rotational symmetry (number of repeats)", ge=3, le=24)],
    style: Annotated[str, Field(default="geometric", description="Style: geometric, floral, or dotted")],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a concentric mandala with rotational symmetry."""
    return await execute_drawing(
        lambda t, s: draw_mandala(t, s, layers=layers, symmetry=symmetry, style=style, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_rosette(
    petals: Annotated[int, Field(default=6, description="Number of petals", ge=3, le=20)],
    radius: Annotated[float, Field(default=150.0, description="Radius of petals in pixels", ge=30, le=350)],
    filled: Annotated[bool, Field(default=True, description="Fill petals with color")] = True,
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw an overlapping-circles rosette pattern."""
    return await execute_drawing(
        lambda t, s: draw_rosette(t, s, petals=petals, radius=radius, filled=filled, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_polygon_grid(
    polygon: Annotated[str, Field(default="square", description="Polygon type: square, triangle, or hexagon")],
    cell_size: Annotated[float, Field(default=50.0, description="Size of each cell in pixels", ge=15, le=150)],
    rows: Annotated[int, Field(default=6, description="Number of rows", ge=1, le=15)],
    cols: Annotated[int, Field(default=6, description="Number of columns", ge=1, le=15)],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a tessellation grid of triangles, squares, or hexagons."""
    return await execute_drawing(
        lambda t, s: draw_polygon_grid(t, s, polygon=polygon, cell_size=cell_size, rows=rows, cols=cols, palette=palette)
    )


# ── Fractal tools ──────────────────────────────────────────────────────────

@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_fractal_tree(
    depth: Annotated[int, Field(default=8, description="Recursion depth", ge=1, le=12)],
    branch_angle: Annotated[float, Field(default=25.0, description="Branch angle in degrees", ge=10, le=60)],
    season: Annotated[str, Field(default="summer", description="Season: spring, summer, autumn, winter")],
    wind: Annotated[float, Field(default=0.0, description="Wind effect (-10 to 10)", ge=-10, le=10)] = 0.0,
) -> str:
    """Draw a beautiful recursive fractal tree with seasonal colours."""
    return await execute_drawing(
        lambda t, s: draw_fractal_tree(t, s, depth=depth, branch_angle=branch_angle, season=season, wind=wind)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_koch_snowflake(
    depth: Annotated[int, Field(default=4, description="Recursion depth", ge=0, le=6)],
    size: Annotated[float, Field(default=300.0, description="Side length in pixels", ge=50, le=600)],
    fill_color: Annotated[str | None, Field(default=None, description="Fill color (hex or name)")] = None,
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a Koch curve snowflake."""
    return await execute_drawing(
        lambda t, s: draw_koch_snowflake(t, s, depth=depth, size=size, fill_color=fill_color, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_sierpinski(
    depth: Annotated[int, Field(default=5, description="Recursion depth", ge=0, le=8)],
    size: Annotated[float, Field(default=400.0, description="Triangle side length in pixels", ge=50, le=700)],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a Sierpinski triangle fractal."""
    return await execute_drawing(
        lambda t, s: draw_sierpinski(t, s, depth=depth, size=size, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_dragon_curve(
    iterations: Annotated[int, Field(default=12, description="Number of iterations", ge=1, le=16)],
    segment_length: Annotated[float, Field(default=5.0, description="Length of each segment in pixels", ge=1, le=20)],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a Heighway dragon curve fractal."""
    return await execute_drawing(
        lambda t, s: draw_dragon_curve(t, s, iterations=iterations, segment_length=segment_length, palette=palette)
    )


# ── Nature tools ───────────────────────────────────────────────────────────

@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_flower(
    flower_type: Annotated[str, Field(default="rose", description="Flower type: rose, sunflower, daisy, or tulip")],
    petal_count: Annotated[int, Field(default=8, description="Number of petals", ge=4, le=24)],
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a beautiful flower — rose, sunflower, daisy, or tulip."""
    return await execute_drawing(
        lambda t, s: draw_flower(t, s, flower_type=flower_type, petal_count=petal_count, palette=palette)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_landscape(
    time_of_day: Annotated[str, Field(default="day", description="Time: day, sunset, or night")],
    mountains: Annotated[bool, Field(default=True, description="Include mountains")] = True,
    lake: Annotated[bool, Field(default=False, description="Include a lake")] = False,
    trees: Annotated[int, Field(default=3, description="Number of trees", ge=0, le=8)] = 3,
) -> str:
    """Draw a scenic landscape with sky, mountains, lake, and trees."""
    return await execute_drawing(
        lambda t, s: draw_landscape(t, s, time_of_day=time_of_day, mountains=mountains, lake=lake, trees=trees)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_sun_moon(
    celestial_body: Annotated[str, Field(default="sun", description="Body to draw: sun or moon")],
    num_stars: Annotated[int, Field(default=20, description="Number of background stars (moon mode)", ge=0, le=80)] = 20,
    rays: Annotated[int, Field(default=12, description="Number of sun rays", ge=4, le=24)] = 12,
) -> str:
    """Draw a sun or moon scene with optional stars and rays."""
    return await execute_drawing(
        lambda t, s: draw_sun_moon(t, s, celestial_body=celestial_body, num_stars=num_stars, rays=rays)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_house(
    style: Annotated[str, Field(default="cottage", description="House style: cottage, modern, or cabin")],
    wall_color: Annotated[str | None, Field(default=None, description="Wall color (hex or name)")] = None,
    garden: Annotated[bool, Field(default=True, description="Include a garden")] = True,
) -> str:
    """Draw a charming house — cottage, modern, or log cabin."""
    return await execute_drawing(
        lambda t, s: draw_house(t, s, style=style, wall_color=wall_color, garden=garden)
    )


@mcp.tool(
    annotations={"readOnlyHint": False, "destructiveHint": False, "openWorldHint": False},
)
async def turtle_draw_bouquet(
    flower_count: Annotated[int, Field(default=5, description="Number of flowers", ge=1, le=12)],
    vase: Annotated[bool, Field(default=True, description="Include a vase")] = True,
    palette: Annotated[str | None, Field(default=None, description="Color palette")] = None,
) -> str:
    """Draw a flower bouquet arrangement with optional vase."""
    return await execute_drawing(
        lambda t, s: draw_bouquet(t, s, flower_count=flower_count, vase=vase, palette=palette)
    )


# ── Entry point ────────────────────────────────────────────────────────────

def main() -> None:
    """Run the MCP server (stdio transport)."""
    mcp.run()


if __name__ == "__main__":
    main()
