from fractions import Fraction
from math import factorial, log10
from komorebi_math.sequences import reciprocal_coefficients
from komorebi_browser import show_plot, export_file

r, count = 1, 16
if not (type(r) is int and 1 <= r <= 3 and type(count) is int and 2 <= count <= 16):
    raise ValueError("Use r=1..3 and count=2..16 for this experiment.")
ns = list(range(count))
traces = []
flat_traces = []
colors = ["#0067a5", "#b54b00", "#007d60", "#963f87", "#6b58a3", "#89532d", "#353d46"]
symbols = ["circle", "diamond", "square", "triangle-up", "cross", "x", "triangle-down"]
csv = "N,r,n,degree,A,normalized_fraction\n"
for N in range(2, 9):
    a = reciprocal_coefficients(N, count, power=r)
    fractions = [Fraction(a[n], factorial(N*n)) for n in ns]
    if any(v <= 0 for v in fractions):
        raise ValueError("This logarithmic view requires positive coefficients.")
    heights = [log10(v.numerator)-log10(v.denominator) for v in fractions]
    flat_traces.append({"mode": "lines+markers+text", "name": f"N={N}", "cliponaxis": False,
                       "x": ns, "y": heights, "text": [""]*(count-1)+[f"N={N}"],
                       "textposition": "middle right", "textfont": {"size": 15, "color": colors[N-2]},
                       "line": {"color": colors[N-2], "dash": "solid" if N % 2 == 0 else "dash"},
                       "marker": {"symbol": symbols[N-2], "size": 8},
                       "hovertemplate": "n = %{x}<br>log10 normalized value = %{y:.3f}<extra>"+f"N={N}"+"</extra>"})
    traces.append({"type": "scatter3d", "mode": "lines+markers", "name": f"N={N}",
                   "x": ns, "y": [N]*count, "z": heights,
                   "line": {"color": colors[N-2]}, "marker": {"size": 5},
                   "hovertemplate": "n = %{x}<br>N = %{y}<br>log10 normalized value = %{z:.3f}<extra></extra>"})
    csv += "".join(f"{N},{r},{n},{N*n},{a[n]},{fractions[n]}\n" for n in ns)
show_plot(flat_traces,
    {"title": {"text": f"Compare the seven reciprocal families (r={r})"},
     "xaxis": {"title": {"text": "Index n"}, "dtick": 2, "range": [-0.3, count+0.8]},
     "yaxis": {"title": {"text": "Normalized size (log10)"}}},
    description="Read each labelled line from left to right. Its height is log10 of A(n)/(Nn)!. A height of -10 means 10 to the power -10. Each step down is a smaller normalized coefficient. Use the checkboxes to compare fewer families. Equal n at different N means different degrees Nn.")
show_plot(traces,
    {"title": {"text": "The same families in 3D"},
     "scene": {"xaxis": {"title": {"text": "n"}},
               "yaxis": {"title": {"text": "N"}, "dtick": 1},
               "zaxis": {"title": {"text": "log10 value"}}}},
    description="Axes: n is the sequence index, N is the integer spacing, and height is log10 of A(n)/(Nn)!. This is the same data as the 2D chart above. Lines connect samples within a family. There is no interpolation between different N values.")
export_file("reciprocal-landscape-exact.csv", csv)
print(f"Reciprocal landscape: N=2..8, r={r}, n=0..{count-1}")
print("Exact coefficient samples:", 7*count)
print("Secant anchor A_2(0..5):", reciprocal_coefficients(2, 6))
print("Exported exact coefficients. Plot heights are approximate logarithms.")
