"""This module contains the utils for the ``workshops`` app"""

import io

from django.utils.translation import ugettext as _

from mtp.apps.common import xls
from mtp.apps.workshops.models import (
    Workshop, WorkshopStepQuestion,
    WorkshopStepQuestionUserAnswer
)


# pylint: disable=too-many-branches,too-many-locals,too-many-nested-blocks
def export_workshop_stat_raw(session):
    """Export the workshops statistics for a given training session

    Parameters
    ----------
    session: ``mtp.apps.trainings.models.TrainingSession`` instance
        The session we want to compute the statistics for

    Returns
    -------
    tuple: A tuple with 3 entries:
        - global_stats: list
        - per_workshop_stats: dict
        - per_workshop_stats_raw: dict

    """

    training = session.training
    workshops = Workshop.objects.non_deleted().for_training(training)

    # Store the questions directly on the workshop instance
    for workshop in workshops:
        workshop.questions = WorkshopStepQuestion.objects.non_deleted().for_workshop(workshop)

    # INIT TAB THAT WILL STORE DATA
    global_stats = []
    per_workshop_stats = {}
    per_workshop_stats_raw = {}

    first_row_global = []
    first_row_global.append((_('first name'), "NAMES_HEADER_STYLE"))
    first_row_global.append((_('last name'), "NAMES_HEADER_STYLE"))

    for workshop in workshops:
        first_row_global.append((workshop.name, "PRIMARY_HEADER"))
        first_row_w = []
        first_row_raw_w = []
        second_row_raw_w = []

        first_row_w.append((_('first name'), "NAMES_HEADER_STYLE"))
        first_row_w.append((_('last name'), "NAMES_HEADER_STYLE"))

        first_row_raw_w.append("")
        first_row_raw_w.append("")
        second_row_raw_w.append((_('first name'), "NAMES_HEADER_STYLE"))
        second_row_raw_w.append((_('last name'), "NAMES_HEADER_STYLE"))

        for question in workshop.questions:
            first_row_w.append((question.title, "PRIMARY_HEADER"))
            first_row_raw_w.append((question.title, "PRIMARY_HEADER"))
            first = True
            if question.answers.non_deleted().count() == 0:
                second_row_raw_w.append((question.title, "SECONDARY_HEADER"))
            else:
                for answer in question.answers.non_deleted():
                    if first:
                        first = False
                    else:
                        first_row_raw_w.append(("", "EMPTY"))
                    if answer.is_correct:
                        second_row_raw_w.append((answer.label, "TERTIARY_HEADER"))
                    else:
                        second_row_raw_w.append((answer.label, "SECONDARY_HEADER"))

        first_row_w.append((_('total'), "TERTIARY_HEADER"))
        per_workshop_stats[workshop.id] = []
        per_workshop_stats[workshop.id].append(first_row_w)
        per_workshop_stats_raw[workshop.id] = []
        per_workshop_stats_raw[workshop.id].append(first_row_raw_w)
        per_workshop_stats_raw[workshop.id].append(second_row_raw_w)

    first_row_global.append((_('total'), "TERTIARY_HEADER"))
    global_stats.append(first_row_global)

    # PROCESS DATA EXTRACTION
    global_stats_d = {}
    per_workshop_stats_d = {}
    per_workshop_stats_raw_d = {}

    users = session.users.all()
    users_count = users.count()
    users_index = []
    for user in users:
        users_index.append(user)

    total_global = [0] * users_count

    for workshop in workshops:
        global_stats_d[workshop.id] = [0] * users_count
        per_workshop_stats_d[workshop.id] = {}
        per_workshop_stats_raw_d[workshop.id] = {}
        for question in workshop.questions:
            per_workshop_stats_d[workshop.id][question.id] = [0] * users_count
            per_workshop_stats_raw_d[workshop.id][question.id] = [None] * users_count
            answers = WorkshopStepQuestionUserAnswer.objects.non_deleted().filter(
                question=question,
                user__in=users,
                training_session_id=session.pk,
            ).select_related(
                'answer',
                'user'
            )
            for answer in answers:
                if answer.answer:
                    _index = users_index.index(answer.user)
                    per_workshop_stats_d[workshop.id][
                        question.id
                    ][_index] += answer.answer.points
                    global_stats_d[workshop.id][_index] += answer.answer.points
                    total_global[_index] += answer.answer.points

                    if not per_workshop_stats_raw_d[workshop.id][question.id][_index]:
                        per_workshop_stats_raw_d[workshop.id][question.id][_index] = []

                    per_workshop_stats_raw_d[workshop.id][
                        question.id
                    ][_index].append(answer.answer)
                else:
                    per_workshop_stats_raw_d[workshop.id][question.id][
                        users_index.index(answer.user)] = answer.text

    # FILL TAB
    for index, user in enumerate(users):
        user_row_global = []
        user_row_global.append((user.first_name, "NAMES_HEADER_STYLE"))
        user_row_global.append((user.last_name, "NAMES_HEADER_STYLE"))
        for workshop in workshops:
            user_row_global.append((global_stats_d[workshop.id][index], "DEFAULT"))
            workshop_row = []
            workshop_row.append((user.first_name, "NAMES_STYLE"))
            workshop_row.append((user.last_name, "NAMES_STYLE"))
            for question in workshop.questions:
                workshop_row.append(
                    (
                        per_workshop_stats_d[workshop.id][question.id][index],
                        "DEFAULT"
                    )
                )
            workshop_row.append((global_stats_d[workshop.id][index], "DEFAULT"))
            per_workshop_stats[workshop.id].append(workshop_row)

            workshop_row_raw = []
            workshop_row_raw.append((user.first_name, "NAMES_STYLE"))
            workshop_row_raw.append((user.last_name, "NAMES_STYLE"))
            for question in workshop.questions:
                if question.answers.non_deleted().count() == 0:
                    workshop_row_raw.append(
                        (
                            per_workshop_stats_raw_d[workshop.id][question.id][index],
                            "DEFAULT"
                        )
                    )
                else:
                    for answer in question.answers.non_deleted():

                        question_answers = per_workshop_stats_raw_d[workshop.id][
                            question.id
                        ][index]

                        if not question_answers:
                            workshop_row_raw.append(("", "DEFAULT"))
                        elif answer in question_answers:
                            workshop_row_raw.append(("X", "GOOD_ANSWER_STYLE"))
                        else:
                            workshop_row_raw.append(("", "DEFAULT"))

            per_workshop_stats_raw[workshop.id].append(workshop_row_raw)

        user_row_global.append((total_global[index], "DEFAULT"))
        global_stats.append(user_row_global)

    return global_stats, per_workshop_stats, per_workshop_stats_raw


def export_workshop_stat_xls(session):
    """Build an excel file containing the workshops stats of a given training session

    Parameters
    ----------
    session: ``mtp.apps.trainings.models.TrainingSession`` instance
        The session we want to build the file for

    Returns
    -------
    xls_file: ``XLSWriter`` instance

    """

    xls_file = io.BytesIO()
    xls_writer = xls.XLSWriter(xls_file)

    global_stats, per_workshop_stats, per_workshop_stats_raw = export_workshop_stat_raw(
        session)

    sheet_name = xls_writer.add_sheet('global')
    xls_writer.writerows(global_stats, sheet_name)

    workshops = Workshop.objects.non_deleted().for_training(session.training)

    for __, workshop in enumerate(workshops):

        w_name = workshop.name
        first_sheet_name = w_name
        first_sheet_name = xls_writer.add_sheet(first_sheet_name)
        xls_writer.writerows(per_workshop_stats[workshop.id], first_sheet_name)
        second_sheet_name = 'verbatim - %s' % w_name
        second_sheet_name = xls_writer.add_sheet(second_sheet_name)
        xls_writer.writerows(per_workshop_stats_raw[workshop.id], second_sheet_name)

    xls_writer.save()

    return xls_file
