# Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import Union

from participation.models import Note, Participation, Passage, Pool, Team, Tournament
from registration.models import Payment
from tfjm.lists import get_sympa_client


def create_team_participation(instance, created, raw, **_):
    """
    When a team got created, create an associated participation.
    """
    if not raw:
        participation = Participation.objects.get_or_create(team=instance)[0]
        participation.save()
        if not created:
            participation.team.create_mailing_list()


def update_mailing_list(instance: Team, raw, **_):
    """
    When a team name or trigram got updated, update mailing lists
    """
    if instance.pk and not raw:
        old_team = Team.objects.get(pk=instance.pk)
        if old_team.trigram != instance.trigram:
            # Delete old mailing list, create a new one
            old_team.delete_mailing_list()
            instance.create_mailing_list()
            # Subscribe all team members in the mailing list
            for student in instance.students.all():
                get_sympa_client().subscribe(student.user.email, f"equipe-{instance.trigram.lower()}", False,
                                             f"{student.user.first_name} {student.user.last_name}")
            for coach in instance.coaches.all():
                get_sympa_client().subscribe(coach.user.email, f"equipe-{instance.trigram.lower()}", False,
                                             f"{coach.user.first_name} {coach.user.last_name}")


def create_payments(instance: Participation, created, raw, **_):
    """
    When a participation got created, create an associated payment.
    """
    if instance.valid and not raw:
        for student in instance.team.students.all():
            payment_qs = Payment.objects.filter(registrations=student, final=False)
            if payment_qs.exists():
                payment = payment_qs.get()
            else:
                payment = Payment.objects.create()
                payment.registrations.add(student)
                payment.save()
            payment.amount = instance.tournament.price
            if payment.amount == 0:
                payment.type = "free"
                payment.valid = True
            payment.save()

        if instance.final:
            for student in instance.team.students.all():
                payment_qs = Payment.objects.filter(registrations=student, final=True)
                if payment_qs.exists():
                    payment = payment_qs.get()
                else:
                    payment = Payment.objects.create(final=True)
                    payment.registrations.add(student)

                    payment_regional = Payment.objects.get(registrations=student, final=False)
                    if payment_regional.type == 'scholarship':
                        payment.type = 'scholarship'
                        with open(payment_regional.receipt.path, 'rb') as f:
                            payment.receipt.save(payment_regional.receipt.name, f)
                        payment.additional_information = payment_regional.additional_information
                        payment.fee = 0
                        payment.valid = payment_regional.valid
                    payment.save()
                payment.amount = Tournament.final_tournament().price
                if payment.amount == 0:
                    payment.type = "free"
                    payment.valid = True
                payment.save()


def create_notes(instance: Union[Passage, Pool], raw, **_):
    if not raw:
        if isinstance(instance, Pool):
            for passage in instance.passages.all():
                create_notes(passage, raw)
            return

        for jury in instance.pool.juries.all():
            Note.objects.get_or_create(jury=jury, passage=instance)