import itertools

from typing import Optional

import matplotlib.pyplot as plt
import seaborn as sns

from pandas import DataFrame

from gad.formats import Course, CurriculumMap


def plot_course_assessments(
    course: Course,
    results: DataFrame,
    curriculum_map: Optional[CurriculumMap] = None,
    sort_tools: bool = False,
    with_dots: bool = True,
):
    """Plot all of the assessment results in this set of data.

    Parameters
    ----------
    sort_tools : bool
      Plot assessment tools in alphabetical order rather than file order

    with_dots : bool
      Show individual
    """

    columns = results.columns
    if sort_tools:
        columns.sort()

    kwargs = {"order": columns, "orient": "h"}

    f = plt.figure()
    plt.xlim(0, 100)

    ax = f.axes[0]

    if curriculum_map:
        for i, tool_name in enumerate(columns):
            try:
                bins = curriculum_map.mapping_for_tool(course, tool_name).bins
                bin_palette = sns.color_palette("husl", len(bins) * 2)

                for j, (low, high) in enumerate(itertools.pairwise(bins)):
                    ax.fill(
                        [low, low, high, high],
                        [i + 0.45, i - 0.45, i - 0.45, i + 0.45],
                        color=bin_palette[j],
                        edgecolor="black",
                        alpha=0.5,
                    )

            except CurriculumMap.MissingMapping:
                pass

    sns.violinplot(results, **kwargs, inner="quart", alpha=0.5)

    if with_dots:
        sns.stripplot(results, **kwargs, linewidth=1, jitter=True)

    return f
