"""Plot iso[2] at n=7 with the depth labels that make it a level resolution
of some plane triangulation."""
import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
from triangulation_gen import enumerate_all_triangulations


def main():
    n, target_idx = 7, 2
    isos = enumerate_all_triangulations(n)
    T = isos[target_idx]

    # Witnessing partition (corresponds to a level resolution of some G)
    levels = {0: 0, 1: 0, 6: 0,  # L_0 = even
              2: 1, 3: 1, 4: 1, 5: 1}  # L_1 = odd
    # Within-parity 2-colorings (the 4-coloring this induces)
    within_color = {0: 'A', 1: 'B', 6: 'B',
                    2: 'C', 5: 'C', 3: 'D', 4: 'D'}
    color_to_hex = {'A': '#ef4444', 'B': '#3b82f6',
                     'C': '#22c55e', 'D': '#f59e0b'}

    # Sanity checks
    even_nodes = [v for v in T.nodes() if levels[v] == 0]
    odd_nodes = [v for v in T.nodes() if levels[v] == 1]
    even_sub = T.subgraph(even_nodes)
    odd_sub = T.subgraph(odd_nodes)
    print(f"L_0 = {sorted(even_nodes)} edges: {sorted(even_sub.edges())} "
          f"bipartite: {nx.is_bipartite(even_sub)}")
    print(f"L_1 = {sorted(odd_nodes)} edges: {sorted(odd_sub.edges())} "
          f"bipartite: {nx.is_bipartite(odd_sub)}")
    # Verify 4-coloring
    for u, v in T.edges():
        assert within_color[u] != within_color[v], \
               f"{u}({within_color[u]})-{v}({within_color[v]})"
    print("4-coloring proper.")

    pos = nx.planar_layout(T)
    centroid = np.mean(list(pos.values()), axis=0)
    for v in pos:
        pos[v] = (pos[v] - centroid) * 1.5

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

    # Panel 1: Level labels (L_0 and L_1)
    ax = axes[0]
    nx.draw_networkx_edges(T, pos, ax=ax, edge_color='#666', width=1.6)
    level_color = {0: '#3b82f6', 1: '#f59e0b'}
    for v in T.nodes():
        ax.scatter(pos[v][0], pos[v][1], c=level_color[levels[v]], s=900,
                   edgecolors='black', linewidths=2.0, zorder=3)
        ax.text(pos[v][0], pos[v][1],
                f"{v}\n$L_{{{levels[v]}}}$",
                fontsize=12, ha='center', va='center',
                fontweight='bold', zorder=4)
    from matplotlib.patches import Patch
    ax.legend(handles=[
        Patch(facecolor=level_color[0], edgecolor='black',
              label='$L_0 = \\{0, 1, 6\\}$  (even parity, source face of $G$)'),
        Patch(facecolor=level_color[1], edgecolor='black',
              label='$L_1 = \\{2, 3, 4, 5\\}$  (odd parity)'),
    ], loc='upper right', fontsize=10)
    ax.set_title(
        "Depth labels that make $T$ a level resolution\n"
        "of some $G$ with face source $S = \\{0, 1, 6\\}$",
        fontsize=12
    )
    ax.set_aspect('equal'); ax.axis('off')

    # Panel 2: induced 4-coloring (refinement of levels)
    ax = axes[1]
    nx.draw_networkx_edges(T, pos, ax=ax, edge_color='#666', width=1.6)
    for v in T.nodes():
        ax.scatter(pos[v][0], pos[v][1],
                   c=color_to_hex[within_color[v]], s=900,
                   edgecolors='black', linewidths=2.0, zorder=3)
        ax.text(pos[v][0], pos[v][1],
                f"{v}\n({within_color[v]})",
                fontsize=12, ha='center', va='center',
                fontweight='bold', zorder=4)
    ax.legend(handles=[
        Patch(facecolor=color_to_hex['A'], edgecolor='black',
              label='A: $\\{0\\}$ (red, $L_0$)'),
        Patch(facecolor=color_to_hex['B'], edgecolor='black',
              label='B: $\\{1, 6\\}$ (blue, $L_0$)'),
        Patch(facecolor=color_to_hex['C'], edgecolor='black',
              label='C: $\\{2, 5\\}$ (green, $L_1$)'),
        Patch(facecolor=color_to_hex['D'], edgecolor='black',
              label='D: $\\{3, 4\\}$ (orange, $L_1$)'),
    ], loc='upper right', fontsize=10)
    ax.set_title(
        "Induced proper 4-coloring (2-coloring within each parity).\n"
        "Card. $(1, 2, 2, 2)$ grouped pairwise as $(3, 4) = (|L_0|, |L_1|)$.",
        fontsize=12
    )
    ax.set_aspect('equal'); ax.axis('off')

    plt.suptitle(
        f"$n = 7$ iso[2] as a level resolution (Def 2.4): "
        f"a partition exists, but the algorithm of \\S5 does not find it.",
        fontsize=13, y=1.02
    )
    plt.tight_layout()
    out = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                        '..', f'missing_iso_n{n}_idx{target_idx}_levels.png')
    plt.savefig(out, dpi=130, bbox_inches='tight')
    print(f"saved: {out}")


if __name__ == "__main__":
    main()
