import os
import sqlite3
import logging
import asyncio
from datetime import datetime, timedelta
try:
    from zoneinfo import ZoneInfo
except ImportError:
    from backports.zoneinfo import ZoneInfo

import disnake
from disnake.ext import commands, tasks
from utils.premium import check_premium_tier

kuby_logger = logging.getLogger("KubyBot")
PARIS_TZ = ZoneInfo("Europe/Paris")

class ReportsDB:
    def __init__(self, db_path):
        self.db_path = db_path
        self._init_db()

    def _init_db(self):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # Table pour les rapports
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS reports (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                guild_id INTEGER NOT NULL,
                author_id INTEGER NOT NULL,
                title TEXT NOT NULL,
                subject TEXT NOT NULL,
                content TEXT NOT NULL,
                status TEXT NOT NULL DEFAULT 'En attente',
                created_at TEXT NOT NULL,
                last_edited_at TEXT,
                channel_id INTEGER NOT NULL,
                role_id_auteur INTEGER
            )
        ''')
        
        # Table pour la configuration du module
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS reports_config (
                guild_id INTEGER PRIMARY KEY,
                viewer_role_id INTEGER
            )
        ''')
        conn.commit()
        conn.close()

    def get_config(self, guild_id):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute("SELECT viewer_role_id FROM reports_config WHERE guild_id = ?", (guild_id,))
        row = cursor.fetchone()
        conn.close()
        return row[0] if row else None

    def set_config(self, guild_id, viewer_role_id):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO reports_config (guild_id, viewer_role_id)
            VALUES (?, ?)
            ON CONFLICT(guild_id) DO UPDATE SET viewer_role_id = excluded.viewer_role_id
        ''', (guild_id, viewer_role_id))
        conn.commit()
        conn.close()

    def add_report(self, guild_id, author_id, title, subject, content, channel_id, role_id_auteur):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        created_at = datetime.now(PARIS_TZ).isoformat()
        cursor.execute('''
            INSERT INTO reports (guild_id, author_id, title, subject, content, status, created_at, channel_id, role_id_auteur)
            VALUES (?, ?, ?, ?, ?, 'En attente', ?, ?, ?)
        ''', (guild_id, author_id, title, subject, content, created_at, channel_id, role_id_auteur))
        report_id = cursor.lastrowid
        conn.commit()
        conn.close()
        return report_id

    def get_report(self, report_id):
        conn = sqlite3.connect(self.db_path)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM reports WHERE id = ?", (report_id,))
        row = cursor.fetchone()
        conn.close()
        return dict(row) if row else None

    def update_report_status(self, report_id, status):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        last_edited_at = datetime.now(PARIS_TZ).isoformat()
        cursor.execute('''
            UPDATE reports
            SET status = ?, last_edited_at = ?
            WHERE id = ?
        ''', (status, last_edited_at, report_id))
        conn.commit()
        conn.close()

    def update_report_content(self, report_id, title, subject, content):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        last_edited_at = datetime.now(PARIS_TZ).isoformat()
        cursor.execute('''
            UPDATE reports
            SET title = ?, subject = ?, content = ?, last_edited_at = ?
            WHERE id = ?
        ''', (title, subject, content, last_edited_at, report_id))
        conn.commit()
        conn.close()

    def delete_report(self, report_id):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute("DELETE FROM reports WHERE id = ?", (report_id,))
        conn.commit()
        conn.close()

    def get_reports(self, guild_id, author_id=None, subject=None, status=None, role_id=None):
        conn = sqlite3.connect(self.db_path)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        query = "SELECT * FROM reports WHERE guild_id = ?"
        params = [guild_id]
        
        if author_id is not None:
            query += " AND author_id = ?"
            params.append(author_id)
        if subject is not None:
            query += " AND subject LIKE ?"
            params.append(f"%{subject}%")
        if status is not None:
            query += " AND status = ?"
            params.append(status)
        if role_id is not None:
            query += " AND role_id_auteur = ?"
            params.append(role_id)
            
        query += " ORDER BY id ASC"
        
        cursor.execute(query, params)
        rows = cursor.fetchall()
        conn.close()
        return [dict(r) for r in rows]

    def get_distinct_subjects(self, guild_id):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute("SELECT DISTINCT subject FROM reports WHERE guild_id = ? ORDER BY subject ASC", (guild_id,))
        rows = cursor.fetchall()
        conn.close()
        return [row[0] for row in rows if row[0]]

    def purge_manual(self, guild_id):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cutoff = (datetime.now(PARIS_TZ) - timedelta(days=7)).isoformat()
        cursor.execute('''
            DELETE FROM reports
            WHERE guild_id = ? AND status != 'Classé' AND created_at < ?
        ''', (guild_id, cutoff))
        deleted_count = cursor.rowcount
        conn.commit()
        conn.close()
        return deleted_count

    def purge_automatic(self):
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cutoff = (datetime.now(PARIS_TZ) - timedelta(days=90)).isoformat()
        cursor.execute('''
            DELETE FROM reports
            WHERE status != 'Classé' AND created_at < ?
        ''', (cutoff,))
        deleted_count = cursor.rowcount
        conn.commit()
        conn.close()
        return deleted_count

class ReportsConfigView(disnake.ui.View):
    def __init__(self, cog, guild_id: int):
        super().__init__(timeout=300)
        self.cog = cog
        self.guild_id = guild_id

    @disnake.ui.role_select(placeholder="Modifier le rôle Lecteur (Viewer)", min_values=1, max_values=1, custom_id="reports_select_viewer_role")
    async def select_viewer_role(self, select: disnake.ui.RoleSelect, interaction: disnake.MessageInteraction):
        if not interaction.author.guild_permissions.administrator:
            return await interaction.response.send_message("❌ Vous devez être administrateur pour configurer ce module.", ephemeral=True)
            
        role = select.values[0]
        self.cog.db.set_config(self.guild_id, role.id)
        
        embed = interaction.message.embeds[0]
        embed.set_field_at(
            0,
            name="👁️ Rôle Lecteur (Viewer)",
            value=f"{role.mention}\n*(Les membres ayant ce rôle peuvent consulter tous les rapports du serveur)*",
            inline=False
        )
        await interaction.response.edit_message(embed=embed, view=self)
        await interaction.followup.send(f"✅ Rôle Lecteur configuré sur {role.mention}", ephemeral=True)

    @disnake.ui.button(label="Purge Manuelle", style=disnake.ButtonStyle.red, emoji="🗑️", custom_id="reports_manual_purge_btn")
    async def manual_purge(self, button: disnake.ui.Button, interaction: disnake.MessageInteraction):
        if not interaction.author.guild_permissions.administrator:
            return await interaction.response.send_message("❌ Vous devez être administrateur pour lancer la purge.", ephemeral=True)
            
        await interaction.response.defer(ephemeral=True)
        deleted_count = self.cog.db.purge_manual(self.guild_id)
        await interaction.followup.send(f"✅ Purge terminée ! **{deleted_count}** rapports (créés il y a > 7 jours et non-classés) ont été définitivement supprimés.", ephemeral=True)

class ReportModal(disnake.ui.Modal):
    def __init__(self, cog):
        self.cog = cog
        components = [
            disnake.ui.TextInput(
                label="Titre du rapport",
                placeholder="Entrez le titre du rapport...",
                custom_id="report_title",
                required=True,
                max_length=100
            ),
            disnake.ui.TextInput(
                label="Objet du rapport",
                placeholder="Ex: Bug, Plainte, Suggestion...",
                custom_id="report_subject",
                required=True,
                max_length=100
            ),
            disnake.ui.TextInput(
                label="Contenu",
                style=disnake.TextInputStyle.paragraph,
                placeholder="Décrivez en détail...",
                custom_id="report_content",
                required=True,
                max_length=2000
            )
        ]
        super().__init__(title="Créer un Rapport", custom_id="report_modal", components=components)

    async def callback(self, interaction: disnake.ModalInteraction):
        title = interaction.text_values["report_title"].strip()
        subject = interaction.text_values["report_subject"].strip()
        content = interaction.text_values["report_content"].strip()
        
        role_id_auteur = interaction.author.top_role.id if interaction.author.roles else None
        
        report_id = self.cog.db.add_report(
            guild_id=interaction.guild.id,
            author_id=interaction.author.id,
            title=title,
            subject=subject,
            content=content,
            channel_id=interaction.channel.id,
            role_id_auteur=role_id_auteur
        )
        
        await interaction.response.send_message(
            f"✅ Votre rapport a été enregistré avec succès sous l'ID **#{report_id}**.",
            ephemeral=True
        )

class EditReportModal(disnake.ui.Modal):
    def __init__(self, cog, report_id, browser_view):
        self.cog = cog
        self.report_id = report_id
        self.browser_view = browser_view
        
        report = self.cog.db.get_report(report_id)
        
        components = [
            disnake.ui.TextInput(
                label="Modifier le titre",
                value=report['title'],
                custom_id="edit_title",
                required=True,
                max_length=100
            ),
            disnake.ui.TextInput(
                label="Modifier l'objet",
                value=report['subject'],
                custom_id="edit_subject",
                required=True,
                max_length=100
            ),
            disnake.ui.TextInput(
                label="Modifier le contenu",
                style=disnake.TextInputStyle.paragraph,
                value=report['content'],
                custom_id="edit_content",
                required=True,
                max_length=2000
            )
        ]
        super().__init__(title=f"Modifier le Rapport #{report_id}", custom_id=f"edit_modal_{report_id}", components=components)

    async def callback(self, interaction: disnake.ModalInteraction):
        report = self.cog.db.get_report(self.report_id)
        if not report:
            return await interaction.response.send_message("❌ Ce rapport n'existe plus.", ephemeral=True)
        if report['status'] in ['Traité', 'Classé']:
            return await interaction.response.send_message("❌ Ce rapport a été traité ou classé et ne peut plus être modifié.", ephemeral=True)
            
        title = interaction.text_values["edit_title"].strip()
        subject = interaction.text_values["edit_subject"].strip()
        content = interaction.text_values["edit_content"].strip()
        
        self.cog.db.update_report_content(self.report_id, title, subject, content)
        
        updated_report = self.cog.db.get_report(self.report_id)
        
        for idx, r in enumerate(self.browser_view.reports):
            if r['id'] == self.report_id:
                self.browser_view.reports[idx] = updated_report
                break
                
        self.browser_view.update_components()
        
        await interaction.response.defer(ephemeral=True)
        await interaction.message.edit(embed=self.browser_view.get_embed(), view=self.browser_view)
        await interaction.followup.send("✅ Votre rapport a été modifié avec succès.", ephemeral=True)

class ReportsFilterView(disnake.ui.View):
    def __init__(self, cog, interaction):
        super().__init__(timeout=300)
        self.cog = cog
        self.interaction = interaction
        self.viewer_id = interaction.author.id
        self.guild_id = interaction.guild.id
        self.is_admin = interaction.author.guild_permissions.administrator
        
        viewer_role_id = self.cog.db.get_config(self.guild_id)
        self.is_viewer = viewer_role_id in [r.id for r in interaction.author.roles] if viewer_role_id else False
        self.has_global_access = self.is_admin or self.is_viewer
        
        self.selected_user = None
        self.selected_role = None
        self.selected_status = None
        self.selected_subject = None
        
        self.update_components()

    def update_components(self):
        self.clear_items()
        
        # Row 0: Menu Status
        status_options = [
            disnake.SelectOption(label="Tous les statuts", emoji="⚪", value="all", default=(self.selected_status is None)),
            disnake.SelectOption(label="En attente", emoji="🟡", value="En attente", default=(self.selected_status == "En attente")),
            disnake.SelectOption(label="Traité", emoji="🟢", value="Traité", default=(self.selected_status == "Traité")),
            disnake.SelectOption(label="Classé", emoji="🔴", value="Classé", default=(self.selected_status == "Classé"))
        ]
        status_select = disnake.ui.StringSelect(
            placeholder="Filtrer par statut...",
            options=status_options,
            custom_id="reports_filter_status",
            row=0
        )
        async def status_callback(inter: disnake.MessageInteraction):
            val = inter.values[0]
            self.selected_status = None if val == "all" else val
            self.update_components()
            await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
        status_select.callback = status_callback
        self.add_item(status_select)
        
        # Row 1: Menu Catégorie
        subjects = self.cog.db.get_distinct_subjects(self.guild_id)
        if subjects:
            subject_options = [
                disnake.SelectOption(label="Toutes les catégories", emoji="📁", value="all", default=(self.selected_subject is None))
            ]
            for subj in subjects[:24]:
                subject_options.append(
                    disnake.SelectOption(label=subj, value=subj, default=(self.selected_subject == subj))
                )
            subject_select = disnake.ui.StringSelect(
                placeholder="Filtrer par catégorie...",
                options=subject_options,
                custom_id="reports_filter_subject",
                row=1
            )
            async def subject_callback(inter: disnake.MessageInteraction):
                val = inter.values[0]
                self.selected_subject = None if val == "all" else val
                self.update_components()
                await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
            subject_select.callback = subject_callback
            self.add_item(subject_select)
            
        current_row = 2
        
        # Row 2 & 3: Filtres utilisateur / rôle (globaux uniquement)
        if self.has_global_access:
            user_select = disnake.ui.UserSelect(
                placeholder="Filtrer par auteur...",
                min_values=0,
                max_values=1,
                custom_id="reports_filter_user",
                row=current_row
            )
            async def user_callback(inter: disnake.MessageInteraction):
                if inter.values:
                    val = inter.values[0]
                    if isinstance(val, str):
                        self.selected_user = inter.guild.get_member(int(val)) or val
                    else:
                        self.selected_user = val
                else:
                    self.selected_user = None
                self.update_components()
                await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
            user_select.callback = user_callback
            self.add_item(user_select)
            current_row += 1
            
            role_select = disnake.ui.RoleSelect(
                placeholder="Filtrer par rôle auteur...",
                min_values=0,
                max_values=1,
                custom_id="reports_filter_role",
                row=current_row
            )
            async def role_callback(inter: disnake.MessageInteraction):
                if inter.values:
                    val = inter.values[0]
                    if isinstance(val, str):
                        self.selected_role = inter.guild.get_role(int(val)) or val
                    else:
                        self.selected_role = val
                else:
                    self.selected_role = None
                self.update_components()
                await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
            role_select.callback = role_callback
            self.add_item(role_select)
            current_row += 1
            
        # Row 4: Boutons Recherche / Reset
        search_btn = disnake.ui.Button(
            label="Rechercher",
            style=disnake.ButtonStyle.green,
            emoji="🔍",
            custom_id="reports_filter_search",
            row=current_row
        )
        async def search_callback(inter: disnake.MessageInteraction):
            author_filter = None
            if not self.has_global_access:
                author_filter = self.viewer_id
            elif self.selected_user:
                author_filter = self.selected_user.id if hasattr(self.selected_user, "id") else int(self.selected_user)
                
            role_filter_id = None
            if self.selected_role:
                role_filter_id = self.selected_role.id if hasattr(self.selected_role, "id") else int(self.selected_role)
            
            reports = self.cog.db.get_reports(
                guild_id=self.guild_id,
                author_id=author_filter,
                subject=self.selected_subject,
                status=self.selected_status,
                role_id=role_filter_id
            )
            
            if not reports:
                await inter.response.send_message("❌ Aucun rapport ne correspond à votre recherche.", ephemeral=True)
                return
                
            browser = ReportsBrowserView(self.cog, self.interaction, reports, filter_view=self)
            await inter.response.edit_message(embed=browser.get_embed(), view=browser)
            
        search_btn.callback = search_callback
        self.add_item(search_btn)
        
        reset_btn = disnake.ui.Button(
            label="Réinitialiser",
            style=disnake.ButtonStyle.red,
            emoji="❌",
            custom_id="reports_filter_reset",
            row=current_row
        )
        async def reset_callback(inter: disnake.MessageInteraction):
            self.selected_user = None
            self.selected_role = None
            self.selected_status = None
            self.selected_subject = None
            self.update_components()
            await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
        reset_btn.callback = reset_callback
        self.add_item(reset_btn)

    def get_filter_embed(self) -> disnake.Embed:
        """Génère l'embed résumant les filtres actifs."""
        author = self.interaction.author
        lines = []
        lines.append(f"🚦 **Statut** : {self.selected_status or 'Tous'}")
        if self.has_global_access:
            if self.selected_user:
                mention = self.selected_user.mention if hasattr(self.selected_user, 'mention') else f'<@{self.selected_user}>'
                lines.append(f"👤 **Auteur** : {mention}")
            else:
                lines.append("👤 **Auteur** : Tous")
            if self.selected_role:
                mention = self.selected_role.mention if hasattr(self.selected_role, 'mention') else f'<@&{self.selected_role}>'
                lines.append(f"🛡️ **Rôle Auteur** : {mention}")
            else:
                lines.append("🛡️ **Rôle Auteur** : Tous")
        else:
            lines.append(f"👤 **Auteur** : {author.mention} *(accès limité à vos rapports)*")
        lines.append(f"📁 **Objet / Catégorie** : {self.selected_subject or 'Tous'}")
        embed = disnake.Embed(
            title="🔍 Recherche & Filtres de Rapports",
            description="\n".join(lines),
            color=disnake.Color.blurple()
        )
        embed.set_thumbnail(url=author.display_avatar.url)
        return embed

    def get_components_v2(self):
        """Kept for backward compatibility — returns view children only."""
        return self.children

    async def interaction_check(self, interaction: disnake.MessageInteraction) -> bool:
        if interaction.author.id != self.viewer_id:
            await interaction.response.send_message("❌ Vous ne pouvez pas interagir avec ce menu.", ephemeral=True)
            return False
        return True

class ReportsBrowserView(disnake.ui.View):
    def __init__(self, cog, interaction, reports, filter_view=None, current_index=0):
        super().__init__(timeout=600)
        self.cog = cog
        self.interaction = interaction
        self.guild_id = interaction.guild.id
        self.viewer_id = interaction.author.id
        self.is_admin = interaction.author.guild_permissions.administrator
        self.reports = reports
        self.filter_view = filter_view
        self.current_index = current_index
        self.page_index = current_index // 25
        self.update_components()

    def update_components(self):
        self.clear_items()
        
        if not self.reports:
            return
            
        report = self.reports[self.current_index]
        
        # Row 0: StringSelectMenu de selection du rapport
        total_pages = (len(self.reports) + 24) // 25
        start = self.page_index * 25
        end = min(start + 25, len(self.reports))
        
        options = []
        for i in range(start, end):
            rep = self.reports[i]
            title = rep['title']
            if len(title) > 60:
                title = title[:57] + "..."
            label = f"#{rep['id']} - {title}"
            description = f"Statut: {rep['status']} | Objet: {rep['subject']}"
            if len(description) > 100:
                description = description[:97] + "..."
            options.append(
                disnake.SelectOption(
                    label=label,
                    description=description,
                    value=str(i),
                    default=(i == self.current_index)
                )
            )
            
        select_menu = disnake.ui.StringSelect(
            placeholder="Sélectionnez un rapport à lire...",
            options=options,
            custom_id="reports_browser_select",
            row=0
        )
        
        async def select_callback(inter: disnake.MessageInteraction):
            self.current_index = int(inter.values[0])
            self.page_index = self.current_index // 25
            self.update_components()
            await inter.response.edit_message(embed=self.get_embed(), view=self)
            
        select_menu.callback = select_callback
        self.add_item(select_menu)
        
        # Row 1: Boutons de pagination de pages (si > 25 rapports)
        if total_pages > 1:
            prev_btn = disnake.ui.Button(
                label="⬅️ Page précédente",
                style=disnake.ButtonStyle.secondary,
                disabled=(self.page_index == 0),
                custom_id="reports_browser_prev_page",
                row=1
            )
            next_btn = disnake.ui.Button(
                label="➡️ Page suivante",
                style=disnake.ButtonStyle.secondary,
                disabled=(self.page_index >= total_pages - 1),
                custom_id="reports_browser_next_page",
                row=1
            )
            
            async def prev_callback(inter: disnake.MessageInteraction):
                self.page_index -= 1
                self.current_index = self.page_index * 25
                self.update_components()
                await inter.response.edit_message(embed=self.get_embed(), view=self)
                
            async def next_callback(inter: disnake.MessageInteraction):
                self.page_index += 1
                self.current_index = self.page_index * 25
                self.update_components()
                await inter.response.edit_message(embed=self.get_embed(), view=self)
                
            prev_btn.callback = prev_callback
            next_btn.callback = next_callback
            self.add_item(prev_btn)
            self.add_item(next_btn)
            
        # Row 2: Boutons d'Action (Modifier, Supprimer, Retour)
        is_author = (self.viewer_id == report['author_id'])
        is_blocked = report['status'] in ['Traité', 'Classé']
        
        edit_disabled = not is_author or is_blocked
        delete_disabled = not (is_author or self.is_admin) or is_blocked
        
        edit_btn = disnake.ui.Button(
            label="Modifier",
            style=disnake.ButtonStyle.primary,
            emoji="✏️",
            disabled=edit_disabled,
            custom_id="reports_browser_edit",
            row=2
        )
        delete_btn = disnake.ui.Button(
            label="Supprimer",
            style=disnake.ButtonStyle.danger,
            emoji="🗑️",
            disabled=delete_disabled,
            custom_id="reports_browser_delete",
            row=2
        )
        back_btn = disnake.ui.Button(
            label="Retour aux filtres",
            style=disnake.ButtonStyle.secondary,
            emoji="⬅️",
            custom_id="reports_browser_back",
            row=2
        )
        
        async def edit_callback(inter: disnake.MessageInteraction):
            report_fresh = self.cog.db.get_report(report['id'])
            if not report_fresh:
                return await inter.response.send_message("❌ Ce rapport n'existe plus.", ephemeral=True)
            if report_fresh['status'] in ['Traité', 'Classé']:
                return await inter.response.send_message("❌ Ce rapport a été traité ou classé et ne peut plus être modifié.", ephemeral=True)
            if inter.author.id != report_fresh['author_id']:
                return await inter.response.send_message("❌ Seul l'auteur du rapport peut le modifier.", ephemeral=True)
                
            modal = EditReportModal(self.cog, report_fresh['id'], self)
            await inter.response.send_modal(modal)
            
        async def delete_callback(inter: disnake.MessageInteraction):
            report_fresh = self.cog.db.get_report(report['id'])
            if not report_fresh:
                return await inter.response.send_message("❌ Ce rapport n'existe plus.", ephemeral=True)
            if report_fresh['status'] in ['Traité', 'Classé']:
                return await inter.response.send_message("❌ Ce rapport a été traité ou classé et ne peut pas être supprimé.", ephemeral=True)
            is_auth = (inter.author.id == report_fresh['author_id'])
            if not (is_auth or inter.author.guild_permissions.administrator):
                return await inter.response.send_message("❌ Vous n'avez pas la permission de supprimer ce rapport.", ephemeral=True)
                
            self.cog.db.delete_report(report['id'])
            del self.reports[self.current_index]
            
            if not self.reports:
                if self.filter_view:
                    self.filter_view.update_components()
                    await inter.response.edit_message(
                        embed=self.filter_view.get_filter_embed(), view=self.filter_view
                    )
                else:
                    await inter.response.edit_message(
                        content="✅ Le rapport a été supprimé. Plus aucun rapport dans cette recherche.",
                        embed=None, view=None
                    )
                return
                
            if self.current_index >= len(self.reports):
                self.current_index = len(self.reports) - 1
            self.page_index = self.current_index // 25
            
            self.update_components()
            await inter.response.edit_message(embed=self.get_embed(), view=self)
            await inter.followup.send("✅ Rapport supprimé avec succès.", ephemeral=True)

        async def back_callback(inter: disnake.MessageInteraction):
            if self.filter_view:
                self.filter_view.update_components()
                await inter.response.edit_message(
                    embed=self.filter_view.get_filter_embed(), view=self.filter_view
                )
            else:
                new_filter_view = ReportsFilterView(self.cog, self.interaction)
                await inter.response.edit_message(
                    embed=new_filter_view.get_filter_embed(), view=new_filter_view
                )
            
        edit_btn.callback = edit_callback
        delete_btn.callback = delete_callback
        back_btn.callback = back_callback
        self.add_item(edit_btn)
        self.add_item(delete_btn)
        self.add_item(back_btn)
        
        # Row 3: Menu Déroulant "Changer l'état" (Admin uniquement)
        if self.is_admin:
            status_options = [
                disnake.SelectOption(label="En attente", emoji="🟡", value="En attente"),
                disnake.SelectOption(label="Traité", emoji="🟢", value="Traité"),
                disnake.SelectOption(label="Classé", emoji="🔴", value="Classé")
            ]
            status_menu = disnake.ui.StringSelect(
                placeholder="Changer le statut...",
                options=status_options,
                custom_id="reports_browser_status",
                row=3
            )
            
            async def status_callback(inter: disnake.MessageInteraction):
                if not inter.author.guild_permissions.administrator:
                    return await inter.response.send_message("❌ Seuls les administrateurs peuvent modifier le statut.", ephemeral=True)

                old_status = report['status']
                new_status = inter.values[0]

                if old_status == new_status:
                    return await inter.response.send_message(f"ℹ️ Le rapport est déjà en statut **{new_status}**.", ephemeral=True)

                self.cog.db.update_report_status(report['id'], new_status)
                updated_rep = self.cog.db.get_report(report['id'])
                self.reports[self.current_index] = updated_rep

                self.update_components()
                await inter.response.edit_message(embed=self.get_embed(), view=self)
                await inter.followup.send(
                    f"✅ Statut du rapport **#{report['id']}** mis à jour : **{old_status}** → **{new_status}**.",
                    ephemeral=True
                )

                # === Notification DM à l'auteur ===
                status_colors = {
                    "En attente": disnake.Color.yellow(),
                    "Traité": disnake.Color.green(),
                    "Classé": disnake.Color.greyple(),
                }
                status_emojis = {"En attente": "🟡", "Traité": "🟢", "Classé": "🔴"}
                dm_sent = False
                try:
                    author_member = inter.guild.get_member(report['author_id'])
                    if not author_member:
                        author_member = await inter.guild.fetch_member(report['author_id'])

                    if author_member:
                        dm_embed = disnake.Embed(
                            title="📋 Mise à jour de votre rapport",
                            description=(
                                f"Le statut de votre rapport **#{report['id']} — {report['title']}** "
                                f"vient d'être modifié."
                            ),
                            color=status_colors.get(new_status, disnake.Color.blurple()),
                            timestamp=datetime.now(PARIS_TZ)
                        )
                        dm_embed.add_field(
                            name="Ancien statut",
                            value=f"{status_emojis.get(old_status, '⚪')} {old_status}",
                            inline=True
                        )
                        dm_embed.add_field(
                            name="Nouveau statut",
                            value=f"{status_emojis.get(new_status, '⚪')} {new_status}",
                            inline=True
                        )
                        dm_embed.add_field(name="Modifié par", value=inter.author.mention, inline=False)
                        dm_embed.add_field(name="Serveur", value=inter.guild.name, inline=False)
                        dm_embed.set_footer(text=f"Rapport #{report['id']} • {inter.guild.name}")
                        if inter.guild.icon:
                            dm_embed.set_thumbnail(url=inter.guild.icon.url)
                        try:
                            await author_member.send(embed=dm_embed)
                            dm_sent = True
                        except disnake.Forbidden:
                            kuby_logger.info(
                                f"[Rapports] DM impossible pour {author_member} (DMs fermés) — rapport #{report['id']}"
                            )
                        except Exception as e:
                            kuby_logger.error(f"[Rapports] Erreur DM notification: {e}", exc_info=True)
                except disnake.NotFound:
                    pass
                except Exception as e:
                    kuby_logger.error(f"[Rapports] Erreur récupération membre pour DM: {e}", exc_info=True)

                dm_note = " • 📬 Auteur notifié par DM." if dm_sent else " • ⚠️ DM non envoyé (DMs fermés ou membre introuvable)."
                await inter.followup.send(
                    f"ℹ️{dm_note}",
                    ephemeral=True
                )
                
            status_menu.callback = status_callback
            self.add_item(status_menu)

    def get_embed(self):
        if not self.reports:
            return disnake.Embed(
                title="Aucun rapport disponible",
                description="Il n'y a aucun rapport correspondant aux critères.",
                color=disnake.Color.red()
            )
            
        report = self.reports[self.current_index]
        
        status_colors = {
            "En attente": 0xF1C40F,
            "Traité": 0x2ECC71,
            "Classé": 0x95A5A6
        }
        color = status_colors.get(report['status'], 0x3498DB)
        
        status_emojis = {
            "En attente": "🟡 En attente",
            "Traité": "🟢 Traité",
            "Classé": "🔴 Classé"
        }
        status_display = status_emojis.get(report['status'], report['status'])
        
        embed = disnake.Embed(
            title=f"Rapport #{report['id']} : {report['title']}",
            description=report['content'],
            color=color
        )
        embed.add_field(name="📁 Objet / Catégorie", value=report['subject'], inline=True)
        embed.add_field(name="🚦 Statut", value=status_display, inline=True)
        embed.add_field(name="👤 Auteur", value=f"<@{report['author_id']}>", inline=True)
        
        try:
            created_dt = datetime.fromisoformat(report['created_at'])
            created_ts = int(created_dt.timestamp())
            embed.add_field(name="📅 Date de création", value=f"<t:{created_ts}:F> (<t:{created_ts}:R>)", inline=False)
        except Exception:
            embed.add_field(name="📅 Date de création", value=report['created_at'], inline=False)
            
        if report['last_edited_at']:
            try:
                edited_dt = datetime.fromisoformat(report['last_edited_at'])
                edited_str = edited_dt.strftime("%d/%m/%Y à %H:%M")
                embed.set_footer(text=f"Dernière action le {edited_str}")
            except Exception:
                embed.set_footer(text=f"Dernière action le {report['last_edited_at']}")
        else:
            embed.set_footer(text="Rapports Hybrides")
            
        return embed

    async def interaction_check(self, interaction: disnake.MessageInteraction) -> bool:
        if interaction.author.id != self.viewer_id:
            await interaction.response.send_message("❌ Vous ne pouvez pas interagir avec ce menu.", ephemeral=True)
            return False
        return True

class Rapports(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
        self.db_path = os.path.join(self.base_dir, "config.db")
        self.db = ReportsDB(self.db_path)
        self.retention_loop.start()

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

    @tasks.loop(hours=24)
    async def retention_loop(self):
        try:
            deleted_count = self.db.purge_automatic()
            if deleted_count > 0:
                kuby_logger.info(f"🧹 [Rétention] Nettoyage automatique effectué : {deleted_count} rapports de plus de 90 jours (non classés) supprimés.")
        except Exception as e:
            kuby_logger.error(f"❌ [Rétention] Erreur lors du nettoyage automatique: {e}", exc_info=True)

    @retention_loop.before_loop
    async def before_retention_loop(self):
        await self.bot.wait_until_ready()

    @commands.slash_command(name="config-system", description="Configuration du module de rapports (Admin uniquement)")
    @check_premium_tier()
    @commands.has_permissions(administrator=True)
    async def config_system(self, interaction: disnake.ApplicationCommandInteraction, role_viewer: disnake.Role = None):
        guild_id = interaction.guild.id
        
        if role_viewer:
            self.db.set_config(guild_id, role_viewer.id)
            viewer_text = f"{role_viewer.mention}"
        else:
            viewer_role_id = self.db.get_config(guild_id)
            viewer_text = f"<@&{viewer_role_id}>" if viewer_role_id else "Aucun rôle configuré"

        embed = disnake.Embed(
            title="⚙️ Configuration du Système de Rapports",
            description="Gérez les autorisations de consultation globale et effectuez la maintenance.",
            color=disnake.Color.blue()
        )
        embed.add_field(
            name="👁️ Rôle Lecteur (Viewer)",
            value=f"{viewer_text}\n*(Les membres ayant ce rôle peuvent consulter tous les rapports du serveur)*",
            inline=False
        )
        embed.add_field(
            name="🧹 Maintenance & Rétention",
            value="Les rapports vieux de plus de **90 jours** sont automatiquement nettoyés chaque jour, sauf s'ils sont **Classés**.\n\nVous pouvez également lancer une purge manuelle pour supprimer les rapports de plus de **7 jours** non classés.",
            inline=False
        )
        embed.set_footer(text="Système de Rapports Hybride")
        
        view = ReportsConfigView(self, guild_id)
        await interaction.response.send_message(embed=embed, view=view, ephemeral=True)

    @commands.slash_command(name="rapport", description="Ouvrir le formulaire de saisie de rapport")
    @check_premium_tier()
    async def rapport(self, interaction: disnake.ApplicationCommandInteraction):
        await interaction.response.send_modal(ReportModal(self))

    @commands.slash_command(name="consulter_rapport", description="Consulter les rapports du serveur via une interface interactive")
    @check_premium_tier()
    async def consulter_rapport(
        self,
        interaction: disnake.ApplicationCommandInteraction,
        utilisateur: disnake.Member = None,
        categorie: str = None,
        statut: str = commands.Param(None, choices=["En attente", "Traité", "Classé"]),
        role: disnake.Role = None
    ):
        filter_view = ReportsFilterView(self, interaction)
        if utilisateur:
            filter_view.selected_user = utilisateur
        if categorie:
            filter_view.selected_subject = categorie
        if statut:
            filter_view.selected_status = statut
        if role:
            filter_view.selected_role = role
            
        filter_view.update_components()
        await interaction.response.send_message(
            embed=disnake.Embed(
                title="🔍 Recherche & Filtres de Rapports",
                description=(
                    f"🚦 **Statut** : {filter_view.selected_status or 'Tous'}\n"
                    f"📁 **Objet / Catégorie** : {filter_view.selected_subject or 'Tous'}\n"
                    + (f"👤 **Auteur** : {filter_view.selected_user.mention if hasattr(filter_view.selected_user, 'mention') else 'Tous'}\n" if filter_view.has_global_access else f"👤 **Auteur** : {interaction.author.mention} *(accès limité à vos rapports)*\n")
                    + (f"🛡️ **Rôle Auteur** : {filter_view.selected_role.mention if hasattr(filter_view.selected_role, 'mention') else 'Tous'}" if filter_view.has_global_access else "")
                ),
                color=disnake.Color.blurple()
            ),
            view=filter_view,
            ephemeral=True
        )

def setup(bot):
    bot.add_cog(Rapports(bot))
