#!/usr/bin/env python3
import csv
import math
from collections import defaultdict

# include X
include_x = False
# normalize q and Y
normalize = True
# closeness coefficient
closeness = 2
# step size within RGB color space
step = 4

data = []
with open("database.csv") as infile:
    for name, *nums in csv.reader(infile, delimiter=",", quotechar="'"):
        data.append((name, *[float(n) for n in nums]))

counts = defaultdict(int)
results = {}

try:
    with open("best.csv") as infile:
        for r, g, b, name, score in csv.reader(infile, delimiter=",", quotechar="'"):
            results[(int(r), int(g), int(b))] = (name, float(score))
except:
    pass  # file not found, assume no prior results

for r in range(0, 256, step):
    for g in range(0, 256, step):
        for b in range(0, 256, step):
            if (known := results.get((r, g, b), None)) is not None:
                counts[known[0]] += 1
                continue
            norm_color = math.sqrt(r * r + g * g + b * b)
            if norm_color == 0:
                continue
            best_score = None
            best_name = None
            for name, x, yr, yg, yb in data:
                norm = (
                    (norm_color * math.sqrt(yr * yr + yg * yg + yb * yb))
                    if normalize
                    else 1
                )
                score = (x if include_x else 0) - (
                    closeness * (r * yr + g * yg + b * yb) / norm
                )
                if best_score is None or score < best_score:
                    best_score = score
                    best_name = name
            results[(r, g, b)] = (best_name, best_score)
            counts[best_name] += 1

with open("best.csv", "w") as outfile:
    csv.writer(outfile, delimiter=",", quotechar="'").writerows(
        (*k, *v) for k, v in results.items()
    )

with open("counts.csv", "w") as outfile:
    csv.writer(outfile, delimiter=",", quotechar="'").writerows(counts.items())

print(f"Top ten most hit:")
for k in sorted(list(counts), key=counts.get, reverse=True)[:10]:
    print(f"{k} - {counts[k]}")
