"""Command-line interface for harmonic-measure."""

from __future__ import annotations

import argparse
import csv
import sys


def cmd_corners(args):
    """Compute harmonic measure of corner regions."""
    from harmonic_measure import HarmonicMeasure
    from superellipse import Superellipse

    curve = Superellipse(a=args.a, b=args.b, p=args.p)
    hm = HarmonicMeasure(
        curve,
        panels_per_quadrant=args.panels,
        nodes_per_panel=args.nodes,
    )

    omega = hm.measure_corners([0, 0], radius=args.radius)
    arc_len = 2 * 3.14159265358979 * omega

    print(f"Lamé curve: p={args.p} (n={args.p//2}), a={args.a}, b={args.b}")
    print(f"Corner radius: {args.radius}")
    print(f"Harmonic measure: {omega:.10f}")
    print(f"Corner arc length: {arc_len:.10f}")


def cmd_scaling(args):
    """Run scaling diagnostic across exponents."""
    from harmonic_measure import corner_scaling_diagnostic

    ns = args.ns
    ns_arr, arcs, slope = corner_scaling_diagnostic(
        ns,
        a=args.a,
        c=args.c,
        verbose=True,
    )

    print()
    print(f"Fitted slope: {slope:.4f} (expected: -2.0 for right angles)")

    if args.output:
        with open(args.output, "w", newline="") as f:
            w = csv.writer(f)
            w.writerow(["n", "arc_len"])
            for n, arc in zip(ns, arcs):
                w.writerow([n, arc])
        print(f"Saved to {args.output}")


def cmd_convergence(args):
    """Test convergence for a single exponent."""
    from harmonic_measure import corner_arc_len_converged

    arc, u0, params, history = corner_arc_len_converged(
        args.n,
        args.a,
        args.c,
        tol=args.tol,
        quality=args.quality,
        verbose=True,
    )

    print()
    print(f"Converged arc length: {arc:.12f}")
    print(f"Final parameters: {params}")


def cmd_density(args):
    """Plot harmonic measure density."""
    try:
        import matplotlib.pyplot as plt
    except ImportError:
        print("Error: matplotlib required. Install with: pip install harmonic-measure[plot]")
        sys.exit(1)

    from harmonic_measure import HarmonicMeasure
    from superellipse import Superellipse

    curve = Superellipse(a=args.a, b=args.b, p=args.p)
    hm = HarmonicMeasure(curve, panels_per_quadrant=args.panels)

    ax = hm.plot_density([0, 0])

    if args.output:
        plt.savefig(args.output, dpi=150, bbox_inches="tight")
        print(f"Saved to {args.output}")
    else:
        plt.show()


def main():
    parser = argparse.ArgumentParser(
        prog="harmonic-measure",
        description="Harmonic measure computation and diagnostics",
    )
    subparsers = parser.add_subparsers(dest="command", help="Available commands")

    # corners command
    p_corners = subparsers.add_parser("corners", help="Compute corner harmonic measure")
    p_corners.add_argument("--a", type=float, default=1.0, help="x semi-axis")
    p_corners.add_argument("--b", type=float, default=1.0, help="y semi-axis")
    p_corners.add_argument("--p", type=float, default=16.0, help="Exponent (p=2n)")
    p_corners.add_argument("--radius", type=float, default=0.1, help="Corner radius")
    p_corners.add_argument("--panels", type=int, default=4)
    p_corners.add_argument("--nodes", type=int, default=16)
    p_corners.set_defaults(func=cmd_corners)

    # scaling command
    p_scaling = subparsers.add_parser("scaling", help="Scaling diagnostic")
    p_scaling.add_argument("--ns", type=int, nargs="+", default=[8, 12, 16, 24, 32, 48])
    p_scaling.add_argument("--a", type=float, default=1.0)
    p_scaling.add_argument("--c", type=float, default=2.0)
    p_scaling.add_argument("--output", "-o", help="Output CSV file")
    p_scaling.set_defaults(func=cmd_scaling)

    # convergence command
    p_conv = subparsers.add_parser("convergence", help="Test convergence")
    p_conv.add_argument("--n", type=int, default=32, help="Lamé exponent")
    p_conv.add_argument("--a", type=float, default=1.0)
    p_conv.add_argument("--c", type=float, default=2.0)
    p_conv.add_argument("--tol", type=float, default=1e-10)
    p_conv.add_argument("--quality", choices=["fast", "mid", "high"], default="mid")
    p_conv.set_defaults(func=cmd_convergence)

    # density command
    p_density = subparsers.add_parser("density", help="Plot density")
    p_density.add_argument("--a", type=float, default=1.0)
    p_density.add_argument("--b", type=float, default=1.0)
    p_density.add_argument("--p", type=float, default=16.0)
    p_density.add_argument("--panels", type=int, default=8)
    p_density.add_argument("--output", "-o", help="Output image file")
    p_density.set_defaults(func=cmd_density)

    args = parser.parse_args()
    if args.command is None:
        parser.print_help()
        sys.exit(1)

    args.func(args)


if __name__ == "__main__":
    main()
