import discord
from discord import app_commands
from discord.ext import commands, tasks
from datetime import datetime
from zoneinfo import ZoneInfo
from utils.gestion_taches import (
    ajouter_tache, lister_taches_utilisateur, taches_proches,
    update_tache_status, charger_taches, supprimer_tache, sauvegarder_taches
)

PRIORITES = ["Haute", "Moyenne", "Basse", "Critique", "Faible"]

class RappelTacheView(discord.ui.View):
    def __init__(self, tid: str):
        super().__init__(timeout=None)
        self.tid = tid

    @discord.ui.button(label="✅ Marquer comme faite", style=discord.ButtonStyle.success, custom_id="btn_mark_done")
    async def mark_done(self, interaction: discord.Interaction, button: discord.ui.Button):
        success = await update_tache_status(self.tid, "Terminée")
        if success:
            await interaction.response.send_message(
                f"✅ La tâche #{self.tid} a été marquée comme terminée !", ephemeral=True)
        else:
            await interaction.response.send_message(
                "❌ Impossible de mettre à jour la tâche. Peut-être déjà terminée ?", ephemeral=True)
        self.disable_all_items()
        await interaction.message.edit(view=self)

class MesTachesPaginator(discord.ui.View):
    def __init__(self, interaction: discord.Interaction, taches_list: list[tuple], per_page=5):
        super().__init__(timeout=120)
        self.interaction = interaction
        self.taches = taches_list
        self.per_page = per_page
        self.page = 0
        self.max_page = (len(taches_list) - 1) // per_page

    def get_embed(self):
        embed = discord.Embed(title="📝 Vos Tâches Assignées", color=discord.Color.green())
        start = self.page * self.per_page
        end = start + self.per_page
        for tid, t in self.taches[start:end]:
            embed.add_field(
                name=f"#{tid} - {t['titre']}",
                value=f"📅 Échéance : {t['échéance']}\n⚠️ Priorité : {t['priorité']}\n📌 Statut : {t['statut']}",
                inline=False
            )
        embed.set_footer(text=f"Page {self.page + 1} / {self.max_page + 1}")
        return embed

    @discord.ui.button(label="⬅️", style=discord.ButtonStyle.secondary)
    async def previous_page(self, interaction: discord.Interaction, button: discord.ui.Button):
        if interaction.user.id != self.interaction.user.id:
            await interaction.response.send_message("❌ Ce n'est pas votre pagination.", ephemeral=True)
            return
        if self.page > 0:
            self.page -= 1
            await interaction.response.edit_message(embed=self.get_embed(), view=self)
        else:
            await interaction.response.defer()

    @discord.ui.button(label="➡️", style=discord.ButtonStyle.secondary)
    async def next_page(self, interaction: discord.Interaction, button: discord.ui.Button):
        if interaction.user.id != self.interaction.user.id:
            await interaction.response.send_message("❌ Ce n'est pas votre pagination.", ephemeral=True)
            return
        if self.page < self.max_page:
            self.page += 1
            await interaction.response.edit_message(embed=self.get_embed(), view=self)
        else:
            await interaction.response.defer()

class JiraDiscord(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.rappels.start()

    def cog_unload(self):
        self.rappels.cancel()

    async def autocomplete_priorite(self, interaction: discord.Interaction, current: str):
        return [
            app_commands.Choice(name=prio, value=prio)
            for prio in PRIORITES if current.lower() in prio.lower()
        ][:5]

    @app_commands.command(name="nouvelle_tache", description="Créer une nouvelle tâche")
    @app_commands.describe(
        titre="Titre de la tâche",
        description="Description de la tâche",
        assigne="Utilisateur assigné",
        priorite="Niveau de priorité (ex: Haute, Moyenne, Basse)",
        echeance="Date d'échéance au format JJ/MM/AAAA"
    )
    async def nouvelle_tache(
        self, interaction: discord.Interaction, titre: str, description: str,
        assigne: discord.User, priorite: str, echeance: str
    ):
        data = await charger_taches()
        for tid, tache in data.get("taches", {}).items():
            if tache["assigné"] == assigne.id and tache["titre"].lower() == titre.lower():
                return await interaction.response.send_message(
                    f"❌ {assigne.mention} a déjà une tâche avec ce titre.", ephemeral=True)

        try:
            date_obj = datetime.strptime(echeance, "%d/%m/%Y")
            date_str = date_obj.strftime("%Y-%m-%d")
        except ValueError:
            return await interaction.response.send_message(
                "❌ Format de date invalide (JJ/MM/AAAA).", ephemeral=True)

        id_tache = await ajouter_tache(titre, description, assigne.id, priorite, date_str, interaction.user.id)

        embed = discord.Embed(
            title=f"📌 Nouvelle Tâche #{id_tache}",
            description=description,
            color=discord.Color.blurple()
        )
        embed.set_author(name=f"Assignée à {assigne.display_name}", icon_url=assigne.display_avatar.url)
        embed.add_field(name="🗂 Titre", value=titre, inline=False)
        embed.add_field(name="⚠️ Priorité", value=priorite, inline=True)
        embed.add_field(name="📅 Échéance", value=echeance, inline=True)
        embed.set_footer(text=f"Créée par {interaction.user.display_name}", icon_url=interaction.user.display_avatar.url)

        await interaction.response.send_message(embed=embed)

        try:
            await assigne.send(
                f"👋 Bonjour {assigne.display_name},\n\nUne nouvelle tâche t'a été assignée par {interaction.user.mention} :",
                embed=embed
            )
        except Exception:
            pass

    @nouvelle_tache.autocomplete("priorite")
    async def autocomplete_priorite_handler(self, interaction: discord.Interaction, current: str):
        return await self.autocomplete_priorite(interaction, current)

    @app_commands.command(name="mes_taches", description="Lister mes tâches assignées")
    async def mes_taches(self, interaction: discord.Interaction):
        taches = await lister_taches_utilisateur(interaction.user.id)
        if not taches:
            await interaction.response.send_message("🚫 Aucune tâche ne vous est assignée.", ephemeral=True)
            return

        taches_list = list(taches.items())
        if len(taches_list) <= 5:
            embed = discord.Embed(title="📝 Vos Tâches Assignées", color=discord.Color.green())
            for tid, t in taches_list:
                embed.add_field(
                    name=f"#{tid} - {t['titre']}",
                    value=f"📅 Échéance : {t['échéance']}\n⚠️ Priorité : {t['priorité']}\n📌 Statut : {t['statut']}",
                    inline=False
                )
            await interaction.response.send_message(embed=embed, ephemeral=True)
        else:
            view = MesTachesPaginator(interaction, taches_list)
            await interaction.response.send_message(embed=view.get_embed(), view=view, ephemeral=True)

    @app_commands.command(name="update_tache", description="Mettre à jour le statut et la priorité d'une tâche")
    @app_commands.describe(
        id_tache="ID de la tâche à mettre à jour",
        statut="Nouveau statut de la tâche",
        priorite="Nouvelle priorité (optionnel)"
    )
    async def update_tache(
        self, interaction: discord.Interaction, id_tache: str, statut: str, priorite: str = None
    ):
        data = await charger_taches()
        if id_tache not in data.get("taches", {}):
            return await interaction.response.send_message("❌ Tâche non trouvée.", ephemeral=True)

        tache = data["taches"][id_tache]
        if tache["assigné"] != interaction.user.id:
            return await interaction.response.send_message("❌ Vous ne pouvez pas mettre à jour le statut de cette tâche.", ephemeral=True)

        statut_update = await update_tache_status(id_tache, statut)
        priorite_update = True
        if priorite:
            tache["priorité"] = priorite
            await sauvegarder_taches(data)

        if statut_update and priorite_update:
            await interaction.response.send_message(
                f"✅ Le statut de la tâche #{id_tache} a été mis à jour à **{statut}**." +
                (f"\nLa priorité est maintenant **{priorite}**." if priorite else ""),
                ephemeral=True
            )
            if tache["créé_par"] != interaction.user.id:
                try:
                    creator = await self.bot.fetch_user(tache["créé_par"])
                    await creator.send(
                        f"🔔 La tâche #{id_tache} que vous avez créée a été mise à jour par {interaction.user.mention} :\n"
                        f"**Nouveau statut** : {statut}" +
                        (f"\n**Nouvelle priorité** : {priorite}" if priorite else "")
                    )
                except Exception:
                    pass
        else:
            await interaction.response.send_message("❌ Erreur lors de la mise à jour de la tâche.", ephemeral=True)

    @update_tache.autocomplete("priorite")
    async def autocomplete_priorite_update(self, interaction: discord.Interaction, current: str):
        return await self.autocomplete_priorite(interaction, current)

    @app_commands.command(name="supprimer_tache", description="Supprimer une tâche")
    @app_commands.describe(
        id_tache="ID de la tâche à supprimer"
    )
    async def supprimer_tache_cmd(self, interaction: discord.Interaction, id_tache: str):
        data = await charger_taches()
        if id_tache not in data.get("taches", {}):
            return await interaction.response.send_message("❌ Tâche non trouvée.", ephemeral=True)

        tache = data["taches"][id_tache]
        perms = interaction.user.guild_permissions
        can_delete = (
            tache["créé_par"] == interaction.user.id or
            tache["assigné"] == interaction.user.id or
            perms.administrator
        )
        if not can_delete:
            return await interaction.response.send_message("❌ Vous ne pouvez pas supprimer cette tâche.", ephemeral=True)

        success = await supprimer_tache(id_tache)
        if success:
            await interaction.response.send_message(f"🗑️ La tâche #{id_tache} a été supprimée.", ephemeral=True)
        else:
            await interaction.response.send_message("❌ Erreur lors de la suppression de la tâche.", ephemeral=True)

    @tasks.loop(seconds=30)
    async def rappels(self):
        now = datetime.now(ZoneInfo("Europe/Paris"))
        if now.hour == 9 and now.minute == 0:
            taches = await taches_proches()
            for tid, t in taches.items():
                try:
                    user = await self.bot.fetch_user(t["assigné"])
                    embed = discord.Embed(
                        title=f"🔔 Rappel Tâche #{tid}",
                        description=t["description"],
                        color=discord.Color.orange()
                    )
                    embed.add_field(name="🗂 Titre", value=t["titre"], inline=False)
                    embed.add_field(name="⚠️ Priorité", value=t["priorité"], inline=True)
                    embed.add_field(name="📅 Échéance", value=t["échéance"], inline=True)
                    embed.set_footer(text="Clique sur le bouton si tu as fini !")
                    view = RappelTacheView(tid)
                    await user.send(embed=embed, view=view)
                except Exception:
                    continue

    @rappels.before_loop
    async def avant_rappel(self):
        await self.bot.wait_until_ready()

async def setup(bot):
    await bot.add_cog(JiraDiscord(bot))