from collections import defaultdict
from sys import argv

import matplotlib.pyplot as plt
import numpy as np


def read_points(filename: str) -> list[tuple[float, float, str]]:
    points = []
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#"):
                parts = line.split()
                if len(parts) >= 3:
                    x = float(parts[0])
                    y = float(parts[1])
                    label = parts[2]
                    points.append((x, y, label))
    return points


def main() -> None:
    points = read_points(argv[1])

    plt.figure(figsize=(8.27, 11.69))
    plt.xlim(0, 30)
    plt.ylim(0, 20)
    plt.gca().set_aspect("equal", adjustable="box")
    plt.grid(True, linewidth=0.3)
    plt.xticks(range(0, 31, 2))
    plt.yticks(range(0, 21, 2))

    grouped = defaultdict(list)
    for x, y, phi in points:
        grouped[phi].append((x, y))

    for x, y, label in points:
        plt.scatter(x, y, color="red", s=15)
        plt.text(x + 0.3, y + 0.3, label, fontsize=9)

    for phi, coords in grouped.items():
        coords.sort(key=lambda p: p[1])
        xs, ys = zip(*coords)
        plt.plot(xs, ys, linewidth=0.8, label=f"φ={phi} В")

    if int(argv[2]):
        theta = np.linspace(0, 2 * np.pi, 200)
        cx, cy = 15, 9

        for r in [5, 6]:
            x = cx + r * np.cos(theta)
            y = cy + r * np.sin(theta)
            plt.plot(x, y, color="blue", linewidth=1)

    plt.xlabel("X (см)")
    plt.ylabel("Y (см)")
    plt.title("Эквипотенциальные линии")
    plt.savefig("points.png", dpi=300)


if __name__ == "__main__":
    main()
