"""Nature drawings: flowers, landscapes, sun/moon, houses, bouquets."""

import math
import random
import turtle

from turtle_mcp.utils import (
    get_palette, palette_color, make_turtle,
    draw_filled_circle, draw_filled_rect, lerp_color,
)


# ---------------------------------------------------------------------------
# Flowers
# ---------------------------------------------------------------------------

def draw_flower(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                flower_type: str = "rose", petal_count: int = 8,
                palette: str | None = None) -> None:
    """Draw a single flower of the given type."""
    colors = get_palette(palette)

    # Stem
    t.penup()
    t.goto(0, -200)
    t.pendown()
    t.pensize(4)
    t.pencolor("#228B22")
    t.setheading(90)
    t.forward(200)

    # Leaf on stem
    t.penup()
    t.goto(0, -80)
    t.pendown()
    t.fillcolor("#32CD32")
    t.begin_fill()
    t.setheading(30)
    t.circle(30, 120)
    t.setheading(30 + 180)
    t.circle(30, 120)
    t.end_fill()

    # Draw flower head at (0, 0)
    if flower_type == "sunflower":
        _draw_sunflower(t, 0, 0, petal_count, colors)
    elif flower_type == "daisy":
        _draw_daisy(t, 0, 0, petal_count, colors)
    elif flower_type == "tulip":
        _draw_tulip(t, 0, 0, colors)
    else:  # rose
        _draw_rose(t, 0, 0, petal_count, colors)


def _draw_rose(t: turtle.RawTurtle, cx: float, cy: float,
               petals: int, colors: list[str]) -> None:
    for i in range(petals):
        angle = 360 * i / petals
        color = palette_color(colors, i)
        t.penup()
        t.goto(cx, cy)
        t.setheading(angle)
        t.pendown()
        t.fillcolor(color)
        t.pencolor(color)
        t.begin_fill()
        t.circle(40, 60)
        t.left(120)
        t.circle(40, 60)
        t.end_fill()
    # Centre
    draw_filled_circle(t, cx, cy, 12, palette_color(colors, petals))


def _draw_sunflower(t: turtle.RawTurtle, cx: float, cy: float,
                    petals: int, colors: list[str]) -> None:
    # Petals
    for i in range(petals):
        angle = 360 * i / petals
        t.penup()
        t.goto(cx, cy)
        t.setheading(angle)
        t.forward(30)
        t.pendown()
        t.fillcolor("#FFD700")
        t.pencolor("#DAA520")
        t.begin_fill()
        t.setheading(angle)
        # Elongated petal
        for _ in range(2):
            t.circle(20, 90)
            t.circle(5, 90)
        t.end_fill()
    # Brown centre
    draw_filled_circle(t, cx, cy, 25, "#8B4513")
    # Seeds pattern
    for i in range(20):
        a = i * 137.508  # golden angle
        r = math.sqrt(i) * 4
        x = cx + r * math.cos(math.radians(a))
        y = cy + r * math.sin(math.radians(a))
        draw_filled_circle(t, x, y, 2, "#654321")


def _draw_daisy(t: turtle.RawTurtle, cx: float, cy: float,
                petals: int, colors: list[str]) -> None:
    for i in range(petals):
        angle = 360 * i / petals
        t.penup()
        t.goto(cx, cy)
        t.setheading(angle)
        t.pendown()
        t.fillcolor("white")
        t.pencolor("#DDDDDD")
        t.begin_fill()
        t.forward(45)
        t.left(150)
        t.forward(45)
        t.left(150)
        t.forward(45)
        t.end_fill()
    draw_filled_circle(t, cx, cy, 15, "#FFD700")


def _draw_tulip(t: turtle.RawTurtle, cx: float, cy: float,
                colors: list[str]) -> None:
    color = colors[0]
    # Three overlapping petals
    for offset in [-20, 0, 20]:
        t.penup()
        t.goto(cx + offset, cy - 30)
        t.pendown()
        t.fillcolor(color)
        t.pencolor(color)
        t.begin_fill()
        t.setheading(90)
        t.circle(25, 180)
        t.end_fill()


# ---------------------------------------------------------------------------
# Landscape
# ---------------------------------------------------------------------------

_SKY_COLORS = {
    "day": ("#87CEEB", "#4682B4"),
    "sunset": ("#FF6B35", "#FF8C42"),
    "night": ("#0C1445", "#1A1A2E"),
}


def draw_landscape(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                   time_of_day: str = "day", mountains: bool = True,
                   lake: bool = False, trees: int = 3) -> None:
    """Draw a scenic landscape."""
    sky_top, sky_bottom = _SKY_COLORS.get(time_of_day, _SKY_COLORS["day"])

    # Sky gradient (horizontal stripes)
    for i in range(40):
        frac = i / 39
        color = lerp_color(sky_top, sky_bottom, frac)
        y = 350 - i * 15
        draw_filled_rect(t, -400, y, 800, 15, color)

    # Ground
    ground_color = "#228B22" if time_of_day != "night" else "#1B4332"
    draw_filled_rect(t, -400, -350, 800, 250, ground_color)

    # Mountains
    if mountains:
        _draw_mountains(t, time_of_day)

    # Lake
    if lake:
        _draw_lake(t, time_of_day)

    # Trees
    rng = random.Random(7)
    for i in range(trees):
        tx = -250 + i * (500 // max(trees, 1))
        tx += rng.randint(-30, 30)
        _draw_simple_tree(t, tx, -100 + rng.randint(-30, 10))

    # Sun or moon
    if time_of_day == "night":
        draw_filled_circle(t, 200, 250, 35, "#F5F5DC")
    elif time_of_day == "sunset":
        draw_filled_circle(t, 0, 100, 50, "#FF4500")
    else:
        draw_filled_circle(t, -200, 280, 45, "#FFD700")


def _draw_mountains(t: turtle.RawTurtle, tod: str) -> None:
    mtn_colors = ["#696969", "#808080", "#A9A9A9"] if tod == "night" else ["#6B8E23", "#556B2F", "#8FBC8F"]
    peaks = [(-250, 180), (-80, 250), (100, 200), (280, 230)]
    for i, (px, py) in enumerate(peaks):
        color = mtn_colors[i % len(mtn_colors)]
        t.penup()
        t.goto(px - 150, -100)
        t.pendown()
        t.fillcolor(color)
        t.pencolor(color)
        t.begin_fill()
        t.goto(px, py)
        t.goto(px + 150, -100)
        t.goto(px - 150, -100)
        t.end_fill()


def _draw_lake(t: turtle.RawTurtle, tod: str) -> None:
    color = "#1E90FF" if tod != "night" else "#0C2D48"
    t.penup()
    t.goto(0, -200)
    t.pendown()
    t.fillcolor(color)
    t.pencolor(color)
    t.begin_fill()
    t.circle(100, steps=40)
    t.end_fill()


def _draw_simple_tree(t: turtle.RawTurtle, x: float, y: float) -> None:
    # Trunk
    draw_filled_rect(t, x - 8, y - 50, 16, 50, "#8B4513")
    # Foliage (three circles)
    for dx, dy, r in [(0, 30, 35), (-20, 10, 25), (20, 10, 25)]:
        draw_filled_circle(t, x + dx, y + dy, r, "#228B22")


# ---------------------------------------------------------------------------
# Sun / Moon
# ---------------------------------------------------------------------------

def draw_sun_moon(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                  celestial_body: str = "sun", num_stars: int = 20,
                  rays: int = 12) -> None:
    """Draw a sun or moon scene."""
    if celestial_body == "moon":
        # Night sky
        screen.bgcolor("#0C1445")
        # Stars
        rng = random.Random(42)
        for _ in range(num_stars):
            sx = rng.randint(-380, 380)
            sy = rng.randint(-200, 380)
            sr = rng.uniform(1, 3)
            draw_filled_circle(t, sx, sy, sr, "white")
        # Moon
        draw_filled_circle(t, 0, 80, 80, "#F5F5DC")
        # Crescent shadow
        draw_filled_circle(t, 30, 90, 70, "#0C1445")
    else:
        # Day sky
        screen.bgcolor("#87CEEB")
        # Sun body
        draw_filled_circle(t, 0, 80, 70, "#FFD700")
        # Rays
        t.pensize(4)
        for i in range(rays):
            angle = 360 * i / rays
            t.pencolor("#FFA500")
            t.penup()
            t.goto(0, 80)
            t.setheading(angle)
            t.forward(80)
            t.pendown()
            t.forward(50)
            t.penup()


# ---------------------------------------------------------------------------
# House
# ---------------------------------------------------------------------------

def draw_house(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
               style: str = "cottage", wall_color: str | None = None,
               garden: bool = True) -> None:
    """Draw a house in the given style."""
    wc = wall_color or {"cottage": "#F5DEB3", "modern": "#D3D3D3", "cabin": "#8B4513"}.get(style, "#F5DEB3")
    roof_color = {"cottage": "#8B0000", "modern": "#404040", "cabin": "#654321"}.get(style, "#8B0000")

    # Ground
    draw_filled_rect(t, -400, -350, 800, 200, "#90EE90")

    # Walls
    w, h = 200, 150
    draw_filled_rect(t, -w / 2, -150, w, h, wc)

    # Roof
    t.penup()
    t.goto(-w / 2 - 20, 0)
    t.pendown()
    t.fillcolor(roof_color)
    t.pencolor(roof_color)
    t.begin_fill()
    t.goto(0, 100)
    t.goto(w / 2 + 20, 0)
    t.goto(-w / 2 - 20, 0)
    t.end_fill()

    # Door
    draw_filled_rect(t, -20, -150, 40, 70, "#654321")
    # Door knob
    draw_filled_circle(t, 12, -118, 3, "#FFD700")

    # Windows
    draw_filled_rect(t, -80, -60, 40, 35, "#87CEEB")
    draw_filled_rect(t, 40, -60, 40, 35, "#87CEEB")
    # Window frames
    for wx in [-80, 40]:
        t.pencolor("#FFFFFF")
        t.pensize(2)
        t.penup()
        t.goto(wx + 20, -60)
        t.pendown()
        t.goto(wx + 20, -25)
        t.penup()
        t.goto(wx, -42)
        t.pendown()
        t.goto(wx + 40, -42)

    if style == "cabin":
        # Log lines
        t.pencolor("#5C3317")
        t.pensize(1)
        for ly in range(-140, 0, 15):
            t.penup()
            t.goto(-w / 2, ly)
            t.pendown()
            t.goto(w / 2, ly)

    # Chimney
    draw_filled_rect(t, 50, 40, 25, 65, "#A0522D")

    # Garden
    if garden:
        rng = random.Random(99)
        flower_colors = ["#FF69B4", "#FF6347", "#FFD700", "#9370DB", "#FF4500"]
        for _ in range(8):
            fx = rng.randint(-300, 300)
            fy = rng.randint(-300, -180)
            fc = rng.choice(flower_colors)
            # Stem
            t.pencolor("#228B22")
            t.pensize(2)
            t.penup()
            t.goto(fx, fy)
            t.pendown()
            t.goto(fx, fy + 20)
            # Flower head
            draw_filled_circle(t, fx, fy + 24, 6, fc)


# ---------------------------------------------------------------------------
# Bouquet
# ---------------------------------------------------------------------------

def draw_bouquet(t: turtle.RawTurtle, screen: turtle.TurtleScreen,
                 flower_count: int = 5, vase: bool = True,
                 palette: str | None = None) -> None:
    """Draw a flower bouquet in a vase."""
    colors = get_palette(palette)

    # Vase
    if vase:
        t.penup()
        t.goto(-50, -200)
        t.pendown()
        t.fillcolor("#4682B4")
        t.pencolor("#36648B")
        t.begin_fill()
        # Vase outline
        t.goto(-60, -100)
        t.goto(-40, -50)
        t.goto(40, -50)
        t.goto(60, -100)
        t.goto(50, -200)
        t.goto(-50, -200)
        t.end_fill()

    # Flowers
    rng = random.Random(42)
    for i in range(flower_count):
        # Stem from vase top
        sx = -30 + i * (60 // max(flower_count - 1, 1))
        sy = -50
        # Flower position (fan out)
        angle = -40 + i * (80 // max(flower_count - 1, 1))
        rad = math.radians(90 + angle)
        length = 120 + rng.randint(-20, 20)
        fx = sx + length * math.cos(rad)
        fy = sy + length * math.sin(rad)

        # Stem
        t.pencolor("#228B22")
        t.pensize(3)
        t.penup()
        t.goto(sx, sy)
        t.pendown()
        t.goto(fx, fy)

        # Flower head — simple layered circles
        color = palette_color(colors, i)
        petal_r = 18 + rng.randint(-5, 5)
        for angle_off in range(0, 360, 60):
            px = fx + petal_r * 0.6 * math.cos(math.radians(angle_off))
            py = fy + petal_r * 0.6 * math.sin(math.radians(angle_off))
            draw_filled_circle(t, px, py, petal_r * 0.5, color)
        # Centre
        draw_filled_circle(t, fx, fy, petal_r * 0.3, "#FFD700")

    # Leaves
    for side in [-1, 1]:
        lx = side * 20
        ly = -80
        t.penup()
        t.goto(lx, ly)
        t.pendown()
        t.fillcolor("#32CD32")
        t.pencolor("#228B22")
        t.begin_fill()
        t.setheading(90 + side * 40)
        t.circle(side * 25, 120)
        t.setheading(90 + side * 40 + 180)
        t.circle(side * 25, 120)
        t.end_fill()
