import json

import matplotlib.pyplot as plt
import numpy as np

plt.rcParams["figure.figsize"] = [18, 9]
plt.style.use("dark_background")
plt.subplots_adjust(left=0.05, right=0.99, top=0.95, bottom=0.05)


def colour(k: int):
    k, r = divmod(k, 256)
    k, g = divmod(k, 256)
    k, b = divmod(k, 256)
    return r, g, b


with open("metrics.json", "r") as file:
    entries = json.load(file)


entries_grouped: dict[int, list] = {}


def group_entries():
    for i, entry in entries:
        entries_grouped.setdefault(i, []).append(entry)


group_entries()


def render_halstead(h_colour: bool):
    units = []
    for i, entry in entries:
        x = -i
        y = entry["metrics"]["halstead"]["difficulty"] or 0.0
        nh = hash(entry["name"])
        y += (nh % 201 - 100) / 500
        if h_colour:
            r, g, b = colour(nh)
            units.append((x, y, r, g, b))
        else:
            c = entry["metrics"]["halstead"]["bugs"] or 0.0
            units.append((x, y, c))
    if h_colour:
        X, Y, R, G, B = np.array(units).transpose()
        C = np.array([R, G, B]).transpose() / 255
        C = 0.25 + 0.75 * C
    else:
        X, Y, C = np.array(units).transpose()
    plt.clf()
    plt.scatter(X, Y, s=2.0, c=C)
    plt.savefig("/code/colour.png" if h_colour else "/code/metrics.png")


def render_ploc():
    units = []
    for i, group in entries_grouped.items():
        x = -i
        ys = [
            sum(entry["metrics"]["loc"]["ploc"] for entry in group),
            sum(entry["metrics"]["loc"]["cloc"] for entry in group),
            sum(entry["metrics"]["loc"]["blank"] for entry in group),
        ]
        units.append((x, *ys))
    X, Yp, Yc, Yb = np.array(units).transpose()
    plt.clf()
    plt.axhline(8000, alpha=0.5)
    plt.axhline(7000, alpha=0.5)
    plt.axhline(6000, alpha=0.5)
    plt.axhline(0, alpha=0.5)
    plt.plot(X, Yp, label="code")
    plt.plot(X, Yc, label="comments/docs")
    plt.plot(X, Yb, label="blank")
    fmt, kwargs = ":", dict(alpha=0.5)
    plt.plot(X, Yc * (k := Yp[0] / Yc[0]), fmt, label=f"c/d x{round(k, 1)}", c="C1", **kwargs)
    plt.plot(X, Yb * (k := Yp[0] / Yb[0]), fmt, label=f"blank x{round(k, 1)}", c="C2", **kwargs)
    plt.legend()
    plt.savefig("/code/ploc.png")


render_ploc()
render_halstead(False)
render_halstead(True)