"""Generate SVGs for Guide: Transforms and Layout."""

import math

from pyfreeform import (
    Scene,
    Palette,
    Polygon,
    EntityGroup,
    Dot,
    Line,
    Rect,
    Curve,
    PathStyle,
    map_range,
)

from wiki._generator import save


def generate():
    colors = Palette.midnight()

    # --- 1. Rotation grid ---
    scene = Scene.with_grid(cols=10, rows=10, cell_size=26, background=colors.background)
    for cell in scene.grid:
        nx, ny = cell.normalized_position
        rotation = (nx + ny) * 180
        cell.add_polygon(
            Polygon.square(size=0.6),
            fill=colors.primary,
            opacity=0.5 + nx * 0.5,
            rotation=rotation,
        )
    save(scene, "guide/transforms-rotation-grid.svg")

    # --- 2. Scale comparison ---
    scene = Scene.with_grid(cols=6, rows=1, cell_size=50, background=colors.background)
    scales = [0.2, 0.4, 0.6, 0.8, 0.9, 1.0]
    for i, cell in enumerate(scene.grid):
        s = scales[i]
        group = EntityGroup()
        group.add(Dot(0, 0, radius=15, color=colors.primary))
        group.add(Line(-10, -10, 10, 10, width=2, color=colors.accent))
        cell.add(group)
        group.fit_to_surface(s)
        cell.add_text(f"{s:.1f}", at="bottom", font_size=0.25, color="#aaaacc", baseline="auto")
        cell.add_border(color=colors.grid, width=0.3, opacity=0.3)
    save(scene, "guide/transforms-scale.svg")

    # --- 3. fit_to_surface with at= positions ---
    scene = Scene.with_grid(cols=3, rows=1, cell_size=80, background=colors.background)
    positions = [(0.15, 0.15), (0.5, 0.5), (0.85, 0.85)]
    for i, cell in enumerate(scene.grid):
        at_pos = positions[i]
        group = EntityGroup()
        group.add(Dot(0, 0, radius=18, color=colors.primary, opacity=0.7))
        group.add(Line(-12, 0, 12, 0, width=2, color=colors.accent))
        cell.add(group)
        group.fit_to_surface(0.5, at=at_pos)
        cell.add_border(color=colors.grid, width=0.5, opacity=0.3)
    save(scene, "guide/transforms-fit-at.svg")

    # --- 3b. Fitting modes comparison (3x3: default / rotate / match_aspect) ---
    rad, sw = 50, 5
    arc_colors = ["#FFA726", "#81c995", "#7aafff"]

    def make_logo():
        g = EntityGroup()
        for k, c in enumerate(arc_colors):
            a1 = math.radians(120 * k - 150)
            a2 = math.radians(120 * k - 30)
            g.add(
                Curve(
                    rad * math.cos(a1),
                    rad * math.sin(a1),
                    rad * math.cos(a2),
                    rad * math.sin(a2),
                    curvature=0.55,
                    width=sw,
                    color=c,
                    cap="round",
                )
            )
        return g

    def make_wide_bar():
        g = EntityGroup()
        g.add(
            Rect.at_center(
                (0, 0),
                60,
                20,
                fill=colors.primary,
                stroke=colors.accent,
                stroke_width=1,
            )
        )
        return g

    scene = Scene.with_grid(
        cols=3,
        rows=3,
        cell_width=100,
        cell_height=140,
        background=None,
    )

    # Row 0: column headers
    for col, label in enumerate(["default", "rotate", "match_aspect"]):
        cell = scene.grid[0][col]
        t = cell.add_text(
            label, at=(0.5, 0.9), font_size=0.12, color="#aaaacc", fit=True, baseline="auto"
        )
        cell.add_border(color=colors.grid, width=0.5, opacity=0.3)

    # Row 1-2: shapes × modes
    modes = [{}, {"rotate": True}, {"match_aspect": True}]
    shapes = [(make_wide_bar, "Rect"), (make_logo, "Logo")]
    for row_idx, (factory, _) in enumerate(shapes, start=1):
        for col in range(3):
            cell = scene.grid[row_idx][col]
            group = factory()
            cell.add(group)
            group.fit_to_surface(1.0, **modes[col])
            cell.add_border(color=colors.grid, width=0.5, opacity=0.3)

    scene.trim(top=scene.grid.cell_height * 0.75)
    save(scene, "guide/transforms-fitting-modes.svg")

    # --- 4. Connected network ---
    colors_ocean = Palette.ocean()
    scene = Scene.with_grid(cols=6, rows=5, cell_size=40, background=colors_ocean.background)
    # Place dots in select cells and connect neighbors
    dots = {}
    for cell in scene.grid:
        if (cell.row + cell.col) % 2 == 0:
            dot = cell.add_dot(radius=0.15, color=colors_ocean.primary, opacity=0.8)
            dots[(cell.row, cell.col)] = dot

    conn_style = PathStyle(width=1, color=colors_ocean.line, opacity=0.4)
    for (r, c), dot in dots.items():
        # Connect to right neighbor
        if (r, c + 2) in dots:
            dot.connect(dots[(r, c + 2)], style=conn_style)
        # Connect to below neighbor
        if (r + 2, c) in dots:
            dot.connect(dots[(r + 2, c)], style=conn_style)
    save(scene, "guide/transforms-connections.svg")

    # --- 5. Arrow caps on connections ---
    scene = Scene.with_grid(cols=4, rows=3, cell_size=50, background=colors.background)
    dots_arr = {}
    for cell in scene.grid:
        if (cell.row + cell.col) % 2 == 0:
            dot = cell.add_dot(radius=0.12, color=colors.accent, opacity=0.8)
            dots_arr[(cell.row, cell.col)] = dot

    arrow_style = PathStyle(
        width=1.5,
        color=colors.primary,
        opacity=0.6,
        end_cap="arrow",
    )
    for (r, c), dot in dots_arr.items():
        if (r, c + 2) in dots_arr:
            dot.connect(dots_arr[(r, c + 2)], style=arrow_style)
        if (r + 2, c) in dots_arr:
            dot.connect(dots_arr[(r + 2, c)], style=arrow_style)
    save(scene, "guide/transforms-arrow-caps.svg")

    # --- 6. z_index layering showcase ---
    scene = Scene.with_grid(cols=1, rows=1, cell_size=200, background=colors.background)
    cell = scene.grid[0][0]
    # Layer 0: grid of faint lines
    for i in range(1, 10):
        t = i / 10
        cell.add_line(
            start=(t, 0), end=(t, 1), width=0.5, color=colors.grid, opacity=0.3, z_index=0
        )
        cell.add_line(
            start=(0, t), end=(1, t), width=0.5, color=colors.grid, opacity=0.3, z_index=0
        )
    # Layer 1: large faded ellipse
    cell.add_ellipse(
        at="center",
        rx=0.35,
        ry=0.35,
        fill=colors.primary,
        opacity=0.2,
        z_index=1,
    )
    # Layer 2: hexagon
    cell.add_polygon(
        Polygon.hexagon(size=0.4),
        fill=colors.accent,
        opacity=0.6,
        z_index=2,
    )
    # Layer 3: central dot
    cell.add_dot(at="center", radius=0.06, color="#ffffff", opacity=0.9, z_index=3)
    save(scene, "guide/transforms-z-index.svg")

    # --- 7. map_range utility ---
    colors_sunset = Palette.sunset()
    scene = Scene.with_grid(cols=15, rows=10, cell_size=20, background=colors_sunset.background)
    for cell in scene.grid:
        nx, ny = cell.normalized_position
        # Convert position (0–1) to visual parameters
        rotation = map_range(ny, 0, 1, 0, 90)
        cell.add_polygon(
            Polygon.diamond(size=0.6),
            fill=colors_sunset.primary,
            opacity=map_range(nx + ny, 0, 2, 0.3, 1.0),
            rotation=rotation,
        )
    save(scene, "guide/transforms-map-range.svg")
