# Copyright (C) 2024 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later

from django.core.management import BaseCommand
from django.utils.translation import activate
from participation.models import Team, Tournament
from tfjm.permissions import PermissionType

from ...models import Channel


class Command(BaseCommand):
    """
    Cette commande permet de créer les canaux de chat pour les tournois et les équipes.
    Différents canaux sont créés pour chaque tournoi, puis pour chaque poule.
    Enfin, un canal de communication par équipe est créé.
    """
    help = "Create chat channels for tournaments and teams."

    def handle(self, *args, **kwargs):
        activate('fr')

        # Création de canaux généraux, d'annonces, d'aide jurys et orgas, etc.
        # Le canal d'annonces est accessibles à tous⋅tes, mais seul⋅es les admins peuvent y écrire.
        Channel.objects.update_or_create(
            name="Annonces",
            defaults=dict(
                category=Channel.ChannelCategory.GENERAL,
                read_access=PermissionType.AUTHENTICATED,
                write_access=PermissionType.ADMIN,
            ),
        )

        # Un canal d'aide pour les bénévoles est dédié.
        Channel.objects.update_or_create(
            name="Aide jurys et orgas",
            defaults=dict(
                category=Channel.ChannelCategory.GENERAL,
                read_access=PermissionType.VOLUNTEER,
                write_access=PermissionType.VOLUNTEER,
            ),
        )

        # Un canal de discussion générale en lien avec le tournoi est accessible librement.
        Channel.objects.update_or_create(
            name="Général",
            defaults=dict(
                category=Channel.ChannelCategory.GENERAL,
                read_access=PermissionType.AUTHENTICATED,
                write_access=PermissionType.AUTHENTICATED,
            ),
        )

        # Un canal de discussion entre participant⋅es est accessible à tous⋅tes,
        # dont l'objectif est de faciliter la mise en relation entre élèves afin de constituer une équipe.
        Channel.objects.update_or_create(
            name="Je cherche une équipe",
            defaults=dict(
                category=Channel.ChannelCategory.GENERAL,
                read_access=PermissionType.AUTHENTICATED,
                write_access=PermissionType.AUTHENTICATED,
            ),
        )

        # Un canal de discussion libre est accessible pour tous⋅tes.
        Channel.objects.update_or_create(
            name="Détente",
            defaults=dict(
                category=Channel.ChannelCategory.GENERAL,
                read_access=PermissionType.AUTHENTICATED,
                write_access=PermissionType.AUTHENTICATED,
            ),
        )

        for tournament in Tournament.objects.all():
            # Pour chaque tournoi, on crée un canal d'annonces, un canal général et un de détente,
            # qui sont comme les canaux généraux du même nom mais réservés aux membres du tournoi concerné.
            # Les membres d'un tournoi sont les organisateur⋅rices, les juré⋅es d'une poule du tournoi
            # ainsi que les membres d'une équipe inscrite au tournoi et qui est validée.
            Channel.objects.update_or_create(
                name=f"{tournament.name} - Annonces",
                defaults=dict(
                    category=Channel.ChannelCategory.TOURNAMENT,
                    read_access=PermissionType.TOURNAMENT_MEMBER,
                    write_access=PermissionType.TOURNAMENT_ORGANIZER,
                    tournament=tournament,
                ),
            )

            Channel.objects.update_or_create(
                name=f"{tournament.name} - Général",
                defaults=dict(
                    category=Channel.ChannelCategory.TOURNAMENT,
                    read_access=PermissionType.TOURNAMENT_MEMBER,
                    write_access=PermissionType.TOURNAMENT_MEMBER,
                    tournament=tournament,
                ),
            )

            Channel.objects.update_or_create(
                name=f"{tournament.name} - Détente",
                defaults=dict(
                    category=Channel.ChannelCategory.TOURNAMENT,
                    read_access=PermissionType.TOURNAMENT_MEMBER,
                    write_access=PermissionType.TOURNAMENT_MEMBER,
                    tournament=tournament,
                ),
            )

            # Un canal réservé à tous⋅tes les juré⋅es du tournoi est créé.
            Channel.objects.update_or_create(
                name=f"{tournament.name} - Juré⋅es",
                defaults=dict(
                    category=Channel.ChannelCategory.TOURNAMENT,
                    read_access=PermissionType.JURY_MEMBER,
                    write_access=PermissionType.JURY_MEMBER,
                    tournament=tournament,
                ),
            )

            if tournament.remote:
                # Dans le cadre d'un tournoi distanciel, un canal pour les président⋅es de jury est créé.
                Channel.objects.update_or_create(
                    name=f"{tournament.name} - Président⋅es de jury",
                    defaults=dict(
                        category=Channel.ChannelCategory.TOURNAMENT,
                        read_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
                        write_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
                        tournament=tournament,
                    ),
                )

                for pool in tournament.pools.all():
                    # Pour chaque poule d'un tournoi distanciel, on crée un canal pour les membres de la poule
                    # (équipes et juré⋅es), et un pour les juré⋅es uniquement.
                    Channel.objects.update_or_create(
                        name=f"{tournament.name} - Poule {pool.short_name}",
                        defaults=dict(
                            category=Channel.ChannelCategory.TOURNAMENT,
                            read_access=PermissionType.POOL_MEMBER,
                            write_access=PermissionType.POOL_MEMBER,
                            pool=pool,
                        ),
                    )

                    Channel.objects.update_or_create(
                        name=f"{tournament.name} - Poule {pool.short_name} - Jury",
                        defaults=dict(
                            category=Channel.ChannelCategory.TOURNAMENT,
                            read_access=PermissionType.JURY_MEMBER,
                            write_access=PermissionType.JURY_MEMBER,
                            pool=pool,
                        ),
                    )

        for team in Team.objects.filter(participation__valid=True).all():
            # Chaque équipe validée a le droit à son canal de communication.
            Channel.objects.update_or_create(
                name=f"Équipe {team.trigram}",
                defaults=dict(
                    category=Channel.ChannelCategory.TEAM,
                    read_access=PermissionType.TEAM_MEMBER,
                    write_access=PermissionType.TEAM_MEMBER,
                    team=team,
                ),
            )
