"""Geometric drawings: stars, spirals, mandalas, rosettes, polygon grids."""

import math
import turtle

from turtle_mcp.utils import get_palette, palette_color, make_turtle


# ---------------------------------------------------------------------------
# Stars
# ---------------------------------------------------------------------------

def draw_star(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
              points: int = 5, size: float = 200.0,
              fill_color: str | None = None, palette: str | None = None) -> None:
    """Draw a multi-pointed star centred on the canvas."""
    colors = get_palette(palette)
    fc = fill_color or colors[0]

    angle = 180 - (180 / points)
    t.penup()
    # Position so star is roughly centred
    t.goto(0, size * 0.4)
    t.pendown()
    t.pencolor(colors[1 % len(colors)])
    t.fillcolor(fc)
    t.begin_fill()
    for i in range(points):
        t.forward(size)
        t.right(angle)
    t.end_fill()


# ---------------------------------------------------------------------------
# Spirals
# ---------------------------------------------------------------------------

def draw_spiral(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                spiral_type: str = "archimedean", turns: int = 10,
                palette: str | None = None) -> None:
    """Draw an Archimedean, logarithmic, or Fibonacci spiral."""
    colors = get_palette(palette)
    t.penup()
    t.goto(0, 0)
    t.pendown()
    t.pensize(2)

    if spiral_type == "fibonacci":
        a, b = 1, 1
        x, y = 0.0, 0.0
        for i in range(min(turns, 14)):
            t.pencolor(palette_color(colors, i))
            # Draw quarter-arc for this Fibonacci square
            radius = a * 4
            t.penup()
            t.goto(x, y)
            t.pendown()
            t.circle(radius, 90)
            a, b = b, a + b
    elif spiral_type == "logarithmic":
        a, b_val = 1.0, 0.15
        for i in range(turns * 60):
            angle_rad = math.radians(i * 6)
            r = a * math.exp(b_val * angle_rad)
            x = r * math.cos(angle_rad)
            y = r * math.sin(angle_rad)
            t.pencolor(palette_color(colors, i // 30))
            t.goto(x, y)
    else:  # archimedean
        spacing = 250 / max(turns, 1)
        for i in range(turns * 60):
            angle_deg = i * 6
            r = spacing * angle_deg / 360
            angle_rad = math.radians(angle_deg)
            x = r * math.cos(angle_rad)
            y = r * math.sin(angle_rad)
            t.pencolor(palette_color(colors, i // 30))
            t.goto(x, y)


# ---------------------------------------------------------------------------
# Mandalas
# ---------------------------------------------------------------------------

def draw_mandala(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                 layers: int = 6, symmetry: int = 8,
                 style: str = "geometric", palette: str | None = None) -> None:
    """Draw a concentric-ring mandala with rotational symmetry."""
    colors = get_palette(palette)
    t.pensize(2)
    max_r = 250

    for layer in range(1, layers + 1):
        radius = max_r * layer / layers
        color = palette_color(colors, layer)
        t.pencolor(color)

        for s in range(symmetry):
            angle = 360 * s / symmetry
            t.penup()
            t.goto(0, 0)
            t.setheading(angle)
            t.forward(radius * 0.3)
            t.pendown()

            if style == "floral":
                # Petal-like shapes
                t.fillcolor(color)
                t.begin_fill()
                for _ in range(2):
                    t.circle(radius * 0.25, 90)
                    t.circle(radius * 0.05, 90)
                t.end_fill()
            elif style == "dotted":
                # Circles at radial positions
                t.fillcolor(color)
                t.begin_fill()
                t.circle(radius * 0.08)
                t.end_fill()
            else:  # geometric
                # Lines and shapes
                t.forward(radius * 0.5)
                t.left(60)
                t.forward(radius * 0.2)
                t.right(120)
                t.forward(radius * 0.2)
                t.left(60)

        # Ring outline
        t.penup()
        t.goto(0, -radius)
        t.pendown()
        t.pencolor(palette_color(colors, layer + 1))
        t.circle(radius)


# ---------------------------------------------------------------------------
# Rosettes
# ---------------------------------------------------------------------------

def draw_rosette(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                 petals: int = 6, radius: float = 150.0,
                 filled: bool = True, palette: str | None = None) -> None:
    """Draw an overlapping-circles rosette pattern."""
    colors = get_palette(palette)
    t.pensize(2)

    for i in range(petals):
        angle = 360 * i / petals
        color = palette_color(colors, i)
        t.pencolor(color)
        t.penup()
        t.goto(0, 0)
        t.setheading(angle)
        t.forward(radius * 0.3)
        # Position at bottom of circle
        x, y = t.pos()
        t.goto(x, y - radius * 0.5)
        t.pendown()

        if filled:
            t.fillcolor(color)
            t.begin_fill()
        t.circle(radius * 0.5)
        if filled:
            t.end_fill()

    # Centre circle
    t.penup()
    t.goto(0, -radius * 0.15)
    t.pendown()
    t.pencolor(palette_color(colors, petals))
    t.fillcolor(palette_color(colors, petals))
    t.begin_fill()
    t.circle(radius * 0.15)
    t.end_fill()


# ---------------------------------------------------------------------------
# Polygon grids (tessellations)
# ---------------------------------------------------------------------------

def draw_polygon_grid(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                      polygon: str = "square", cell_size: float = 50.0,
                      rows: int = 6, cols: int = 6,
                      palette: str | None = None) -> None:
    """Draw a tessellation of triangles, squares, or hexagons."""
    colors = get_palette(palette)
    t.pensize(1)

    start_x = -(cols * cell_size) / 2
    start_y = (rows * cell_size) / 2

    if polygon == "hexagon":
        _draw_hex_grid(t, colors, cell_size, rows, cols, start_x, start_y)
    elif polygon == "triangle":
        _draw_tri_grid(t, colors, cell_size, rows, cols, start_x, start_y)
    else:  # square
        _draw_square_grid(t, colors, cell_size, rows, cols, start_x, start_y)


def _draw_square_grid(t: turtle.RawTurtle, colors: list[str],
                      size: float, rows: int, cols: int,
                      sx: float, sy: float) -> None:
    for r in range(rows):
        for c in range(cols):
            color = palette_color(colors, r + c)
            t.penup()
            t.goto(sx + c * size, sy - r * size)
            t.pendown()
            t.pencolor(color)
            t.fillcolor(color)
            t.begin_fill()
            t.setheading(0)
            for _ in range(4):
                t.forward(size)
                t.right(90)
            t.end_fill()


def _draw_tri_grid(t: turtle.RawTurtle, colors: list[str],
                   size: float, rows: int, cols: int,
                   sx: float, sy: float) -> None:
    h = size * math.sqrt(3) / 2
    for r in range(rows):
        for c in range(cols):
            color = palette_color(colors, r + c)
            x = sx + c * (size / 2)
            y = sy - r * h
            t.penup()
            t.goto(x, y)
            t.pendown()
            t.pencolor(color)
            t.fillcolor(color)
            t.begin_fill()
            t.setheading(0)
            if (r + c) % 2 == 0:
                for angle in [0, -120, -120]:
                    t.forward(size)
                    t.right(-angle if angle else 0)
                    if angle:
                        t.left(180 + angle)
                # Simpler approach
                t.end_fill()
                t.begin_fill()
                t.penup()
                t.goto(x, y)
                t.pendown()
                # upward triangle
                t.setheading(0)
                t.forward(size)
                t.left(120)
                t.forward(size)
                t.left(120)
                t.forward(size)
            else:
                # downward triangle
                t.setheading(0)
                t.right(60)
                t.forward(size)
                t.right(60)
                t.forward(size)
                t.right(60)
                t.forward(size)
            t.end_fill()


def _draw_hex_grid(t: turtle.RawTurtle, colors: list[str],
                   size: float, rows: int, cols: int,
                   sx: float, sy: float) -> None:
    h = size * math.sqrt(3)
    for r in range(rows):
        for c in range(cols):
            color = palette_color(colors, r + c)
            x = sx + c * (size * 1.5)
            y = sy - r * h - (h / 2 if c % 2 else 0)
            t.penup()
            t.goto(x + size, y)
            t.pendown()
            t.pencolor(color)
            t.fillcolor(color)
            t.begin_fill()
            t.setheading(60)
            for _ in range(6):
                t.forward(size)
                t.left(60)
            t.end_fill()
