# -*- coding: utf-8 -*-
"""
Team JSON Generator
===================
Ce module parcourt les membres d'un serveur Discord, filtre ceux qui possèdent
un ou plusieurs rôles spécifiés, télécharge leurs avatars et génère un fichier
JSON compatible avec le site de production.

Le JSON attendu ressemble à :
[
  {
    "id": "123456789012345678",
    "name": "Nom affiché",
    "role": "Nom du rôle filtré",
    "avatar": "123456789012345678.png",
    "bio": "",
    "stats": [],
    "skills": [],
    "social": {"discord":"","twitter":"",...}
  },
  ...
]

Le champ ``avatar`` correspond au nom de fichier stocké dans ``website/avatars/``.
"""

import os
import json
import aiohttp
from pathlib import Path
from typing import List
import disnake
from disnake.ext import commands, tasks

# ----------------------------------------------------------------------
# Configuration – variables d'environnement (dans le .env du projet)
# ----------------------------------------------------------------------
TARGET_GUILD_ID = os.getenv("TARGET_GUILD_ID")  # ID du serveur contenant l'équipe
# Liste d'IDs de rôles séparés par des virgules (ex. "123,456,789")
TEAM_ROLE_IDS   = os.getenv("TEAM_ROLE_IDS", "").split(",") if os.getenv("TEAM_ROLE_IDS") else []

# Dossiers où seront stockés les avatars et le JSON final
AVATAR_ROOT = Path(__file__).parents[2] / "website" / "avatars"
AVATAR_ROOT.mkdir(parents=True, exist_ok=True)

JSON_OUTPUT = Path(__file__).parents[2] / "website" / "team.json"

# ----------------------------------------------------------------------
class TeamJSON(commands.Cog):
    """Cog responsable de la génération du JSON d'équipe et du téléchargement des avatars."""

    def __init__(self, bot: commands.Bot):
        self.bot = bot
        # Démarre la tâche quotidienne (synchronisation 24h/24)
        self.sync_daily.start()

    # ------------------------------------------------------------------
    @tasks.loop(hours=24)
    async def sync_daily(self):
        """Tâche planifiée exécutée chaque jour (cron)."""
        await self._generate_team(trigger="cron")

    @sync_daily.before_loop
    async def before_sync(self):
        await self.bot.wait_until_ready()

    # ------------------------------------------------------------------
    async def _download_avatar(self, session: aiohttp.ClientSession, member: disnake.Member) -> str:
        """Télécharge l'avatar du *member* et le sauvegarde dans ``AVATAR_ROOT``.
        Retourne le nom de fichier (ex. ``"123456789.png"``)."""
        avatar_url = str(member.display_avatar.url)
        filename   = f"{member.id}.png"
        dest_path  = AVATAR_ROOT / filename
        try:
            async with session.get(avatar_url) as resp:
                if resp.status == 200:
                    dest_path.write_bytes(await resp.read())
                else:
                    self.bot.logger.warning(
                        f"[TeamJSON] Avatar download failed for {member.id} – HTTP {resp.status}"
                    )
        except Exception as exc:
            self.bot.logger.error(f"[TeamJSON] Exception while downloading avatar {member.id}: {exc}")
        return filename

    # ------------------------------------------------------------------
    async def _generate_team(self, *, trigger: str = "manual") -> None:
        """Construit le JSON de l'équipe et télécharge les avatars.

        Le JSON produit suit exactement le format attendu par le site de production.
        Les champs ``stats``, ``skills`` et ``social`` sont laissés vides car ils ne
        sont pas disponibles via l'API bot.
        """
        if not TARGET_GUILD_ID:
            self.bot.logger.error("[TeamJSON] TARGET_GUILD_ID non défini – arrêt du générateur.")
            return
        if not TEAM_ROLE_IDS:
            self.bot.logger.error("[TeamJSON] TEAM_ROLE_IDS non défini – arrêt du générateur.")
            return

        # Récupération de la guilde
        guild = self.bot.get_guild(int(TARGET_GUILD_ID))
        if not guild:
            try:
                guild = await self.bot.fetch_guild(int(TARGET_GUILD_ID))
            except Exception as exc:
                self.bot.logger.error(f"[TeamJSON] Impossible de récupérer la guilde {TARGET_GUILD_ID}: {exc}")
                return

        # Convertir les IDs de rôle en entiers pour la comparaison
        role_ids = {int(r) for r in TEAM_ROLE_IDS if r.strip()}
        members_data: List[dict] = []

        async with aiohttp.ClientSession() as session:
            async for member in guild.fetch_members(limit=None):
                if member.bot:
                    continue
                # Intersection entre les rôles du membre et les rôles ciblés
                member_role_ids = {r.id for r in member.roles}
                intersect = member_role_ids.intersection(role_ids)
                if not intersect:
                    continue  # le membre ne possède aucun des rôles recherchés

                # On prend le premier rôle correspondant comme "role" dans le JSON
                role_name = next((r.name for r in member.roles if r.id in intersect), "")
                avatar_file = await self._download_avatar(session, member)

                entry = {
                    "id":     str(member.id),
                    "name":   member.display_name,
                    "role":   role_name,
                    "avatar": avatar_file,
                    "bio":    "",   # non récupérable via l'API bot
                    "stats":  [],
                    "skills": [],
                    "social": {
                        "discord":   "",
                        "twitter":   "",
                        "instagram": "",
                        "youtube":   "",
                        "tiktok":    "",
                        "github":    "",
                    },
                }
                members_data.append(entry)

        # Écriture du JSON final
        try:
            JSON_OUTPUT.parent.mkdir(parents=True, exist_ok=True)
            JSON_OUTPUT.write_text(
                json.dumps(members_data, indent=2, ensure_ascii=False),
                encoding="utf-8",
            )
            self.bot.logger.info(
                f"[TeamJSON] JSON généré ({len(members_data)} membres) → {JSON_OUTPUT}"
            )
        except Exception as exc:
            self.bot.logger.error(f"[TeamJSON] Échec de l'écriture du JSON : {exc}")

    # ------------------------------------------------------------------
    @commands.slash_command(
        name="generate_team_json",
        description="Génère le JSON de l'équipe (admin only)"
    )
    @check_premium_tier()
    @commands.has_permissions(administrator=True)
    async def generate_team_json(self, inter: disnake.ApplicationCommandInteraction):
        """Commande manuelle pour (re)générer le JSON et les avatars."""
        await inter.response.defer(ephemeral=True)
        await self._generate_team(trigger="manual")
        await inter.edit_original_response(
            content="✅ JSON de l'équipe généré et avatars synchronisés."
        )

# ----------------------------------------------------------------------
def setup(bot: commands.Bot):
    bot.add_cog(TeamJSON(bot))
