"""Annotated diagram so the user can answer the v_c-rotation
clarification questions.

Shows the 9-vertex L_k with e_0 = (0, 3) highlighted, both candidate
v_c vertices (0 and 3) labelled, and the four (v_c, direction) fans
laid out around each."""
import os
import math
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon, FancyArrowPatch

OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)

n = 9
POS = {i: (math.cos(math.radians(90 - i * 360 / n)),
           math.sin(math.radians(90 - i * 360 / n))) for i in range(n)}
OUTER_EDGES = [(i, (i + 1) % n) for i in range(n)]
CHORDS = [(0, 2), (0, 3), (3, 5), (3, 6), (0, 6), (6, 8)]

# Inner faces
FACES = {
    (0, 1, 2): 0,
    (0, 2, 3): 0,
    (3, 4, 5): 0,
    (3, 5, 6): 0,
    (6, 7, 8): 0,
    (6, 8, 0): 0,
    (0, 3, 6): 1,    # F
}

F_idx_face = (0, 3, 6)
Fp_face = (0, 2, 3)
e0 = (0, 3)


def cw_order_around(v):
    """Sort vertices adjacent to v by clockwise angle (decreasing
    angle from v, starting at angle 90)."""
    adj = set()
    for f in FACES:
        if v in f:
            for u in f:
                if u != v:
                    adj.add(u)
    # angle of each adjacent vertex
    def angle(u):
        return (90 - u * 360 / n) % 360
    return sorted(adj, key=lambda u: -angle(u))


fig, axes = plt.subplots(1, 2, figsize=(14, 7))

palette = {0: '#86efac', 1: '#fde68a'}
edge_pal = {0: '#16a34a', 1: '#d97706'}


def draw_base(ax, title):
    # Fill faces by depth
    for face, depth in FACES.items():
        poly = Polygon([POS[v] for v in face], closed=True,
                       facecolor=palette[depth], edgecolor=edge_pal[depth],
                       linewidth=1.2, alpha=0.5, zorder=0)
        ax.add_patch(poly)

    # Edges
    for (a, b) in OUTER_EDGES + CHORDS:
        color, lw = '#333', 1.2
        if {a, b} == set(e0):
            color, lw = '#dc2626', 3.4  # e_0 highlighted
        ax.plot([POS[a][0], POS[b][0]], [POS[a][1], POS[b][1]],
                color=color, linewidth=lw, zorder=1)

    # Vertices
    for i, (x, y) in POS.items():
        color = '#3b82f6' if i in e0 else '#1f2937'
        size = 470 if i in e0 else 280
        ax.scatter([x], [y], s=size, c=color, edgecolors='black',
                   linewidths=1.2, zorder=2)
        ax.text(x, y, str(i), ha='center', va='center',
                fontsize=11 if i in e0 else 9,
                color='white', fontweight='bold', zorder=3)

    # Annotate F and F'
    cx_F = sum(POS[v][0] for v in F_idx_face) / 3
    cy_F = sum(POS[v][1] for v in F_idx_face) / 3
    ax.text(cx_F, cy_F + 0.1, r'$F$', ha='center', fontsize=14,
            color='#92400e', fontweight='bold', zorder=4)
    ax.text(cx_F, cy_F - 0.1, '(depth 1)', ha='center', fontsize=9,
            color='#92400e', zorder=4)

    cx_Fp = sum(POS[v][0] for v in Fp_face) / 3
    cy_Fp = sum(POS[v][1] for v in Fp_face) / 3
    ax.text(cx_Fp + 0.1, cy_Fp, r"$F'$" + '\n(depth 0)', ha='center',
            fontsize=10, color='#16a34a', fontweight='bold', zorder=4)

    # F''s outer-cycle edge: (2, 3)
    px, py = POS[2], POS[3]
    mid = ((px[0] + py[0]) / 2, (px[1] + py[1]) / 2)
    ax.annotate("outer edge of $F'$",
                xy=(mid[0] + 0.05, mid[1] - 0.05),
                xytext=(1.35, 0.5),
                fontsize=9, color='#16a34a',
                arrowprops=dict(arrowstyle='->', color='#16a34a',
                                lw=1.0))

    ax.set_aspect('equal'); ax.axis('off')
    ax.set_xlim(-1.5, 1.7); ax.set_ylim(-1.4, 1.4)
    ax.set_title(title, fontsize=12)


def annotate_fan(ax, vc, label):
    """Draw arrows around v_c showing CW order of edges."""
    cw_neighbours = cw_order_around(vc)
    # rotate so the e_0 neighbour comes first
    e0_other = [u for u in e0 if u != vc][0]
    idx = cw_neighbours.index(e0_other)
    cw_neighbours = cw_neighbours[idx:] + cw_neighbours[:idx]

    px, py = POS[vc]
    # Draw a partial arc around v_c
    for i, u in enumerate(cw_neighbours):
        # midpoint between v_c and u, slightly inside
        ux, uy = POS[u]
        midx = px * 0.7 + ux * 0.3
        midy = py * 0.7 + uy * 0.3
        # is edge on outer cycle?
        is_outer = (min(vc, u), max(vc, u)) in OUTER_EDGES or \
                   (max(vc, u), min(vc, u)) in OUTER_EDGES
        marker_color = '#1d4ed8' if not is_outer else '#dc2626'
        marker = 'o'
        ax.scatter([midx], [midy], s=120, c=marker_color, marker=marker,
                   edgecolors='white', linewidths=1.5, zorder=5)
        ax.text(midx, midy, str(i + 1), ha='center', va='center',
                fontsize=8, color='white', fontweight='bold', zorder=6)

    # Label
    ax.text(px + 0.05, py + 0.25, label, ha='center',
            fontsize=11, color='#1d4ed8', fontweight='bold')


draw_base(axes[0], r'Option A: $v_c = 0$  (CW order: 1=$(0,3)$, 2=$(0,6)$, 3=$(0,8)$ outer ...)')
annotate_fan(axes[0], 0, r'$v_c = 0$')

draw_base(axes[1], r'Option B: $v_c = 3$  (CW order: 1=$(0,3)$, 2=$(2,3)$ outer ...)')
annotate_fan(axes[1], 3, r'$v_c = 3$')

# Add legend below
fig.text(0.5, 0.02,
         'Blue circles = chord edges (would be switched). '
         'Red circles = outer-cycle edges (algorithm stops here). '
         'Numbers = clockwise order around $v_c$ starting from $e_0$.',
         ha='center', fontsize=10)

fig.tight_layout(rect=[0, 0.04, 1, 1])
out = os.path.join(OUT_DIR, 'fig_v_c_question.png')
fig.savefig(out, dpi=180, bbox_inches='tight')
plt.close(fig)
print(f'wrote {out}')
