import itertools
from typing import Iterable, Literal
import re

from goldberg.operators import Polyhedron

GoldbergClass = Literal["I", "II", "III"]


def group_dict(xs: Iterable, key=None):
    """
    Group the items of `xs` into a dict using `sorted` and `itertools.groupby`.
    `key` is passed to both functions.
    """
    return {i: list(j) for i, j in itertools.groupby(sorted(xs, key=key), key=key)}


def hexagons_to_polyhedron(hexagon_count: int):
    """General Goldberg solution"""
    return Polyhedron(
        face_count=hexagon_count + 12,
        vertex_count=2 * hexagon_count + 20,
        edge_count=3 * hexagon_count + 30,
    )


def link_polyhedronisme(text: str, recipe: str) -> str:
    return f'[{text}](https://levskaya.github.io/polyhedronisme/?recipe={recipe}){{target="_blank"}}'


def parameter_to_class(parameter: tuple[int, int]) -> GoldbergClass:
    if min(*parameter) == 0:
        return "I"
    elif parameter[0] == parameter[1]:
        return "II"
    return "III"


def display_conway(conway_notation: str, seed: str | None = None):
    """
    Display a Conway notation string in LaTeX.
    Indexed operators (u, t, and k) have their indices placed in subscripts.

    If `seed` is given, the notation is applied to it.
    If the notation contains equals signs, these are interpreted as separate recipes to apply.
    """
    # If a seed is given, split at the equals and apply to both sides
    if seed is not None:
        conway_notation = " = ".join(
            operation + seed for operation in conway_notation.split(" = ")
        )

    # Latexify and subscript the numbers in u, t, and k
    return f"${re.sub('([utk])(\\d+)', '\\1_\\2', conway_notation)}$"


def remove_repeats(xs: list[str]) -> list[str]:
    """Mutate a list of strings. Repeated entries are replaced with the empty string."""
    prev = None
    for i, x in enumerate(xs):
        if x == prev:
            xs[i] = ""
        else:
            prev = x

    return xs
