import disnake
from disnake.ext import commands
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import io
import numpy as np
from datetime import datetime, timedelta
from collections import defaultdict

from commandes.ticket.data.storage import get_storage
from commandes.ticket.data.models import TicketStatus
from commandes.ticket.staff_analytics import StaffAnalytics
from utils.premium import check_premium_tier


class StaffRatings(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.slash_command(name="staff-ratings", description="Affiche les évaluations du staff")
    @check_premium_tier()
    async def staff_ratings(self, interaction: disnake.ApplicationCommandInteraction, 
                            team: str = commands.Param(None, description="Filtrer par équipe (optionnel)")):
        """Commande pour afficher les évaluations du staff"""
        await interaction.response.defer(ephemeral=False)
        
        try:
            storage = get_storage()
            analytics = StaffAnalytics(self.bot)
            
            # Get staff list
            staff_list = await analytics.get_staff_list(interaction.guild_id)
            
            if not staff_list:
                await interaction.followup.send("Aucun membre du staff n'a été trouvé.", ephemeral=True)
                return
            
            # Filter by team if specified
            if team:
                # This would require a team mapping in the staff data
                # For now, we'll show all staff
                pass
            
            # Create the rating chart using matplotlib
            chart_buffer = self.create_staff_rating_chart_matplotlib(staff_list)
            
            # Create embed
            embed = disnake.Embed(
                title="📊 Évaluations du Staff",
                description="Performance globale du staff",
                color=disnake.Color.blue(),
                timestamp=datetime.now()
            )
            
            # Add stats
            total_ratings = sum(s['total_ratings'] for s in staff_list)
            avg_rating = sum(s['average_rating'] for s in staff_list if s['total_ratings'] > 0) / len([s for s in staff_list if s['total_ratings'] > 0]) if any(s['total_ratings'] > 0 for s in staff_list) else 0
            
            embed.add_field(
                name="📈 Statistiques",
                value=f"**Membres du staff:** {len(staff_list)}\n"
                        f"**Évaluations totales:** {total_ratings}\n"
                        f"**Note moyenne globale:** {avg_rating:.1f}⭐",
                inline=False
            )
            
            # Send chart
            file = disnake.File(chart_buffer, filename="staff_ratings.png")
            await interaction.followup.send(embed=embed, file=file)
            
        except Exception as e:
            print(f"Error in staff_ratings command: {e}")
            await interaction.followup.send("Une erreur est survenue lors de la génération des statistiques.", ephemeral=True)

    def create_staff_rating_chart_matplotlib(self, staff_list):
        """Create staff rating chart using matplotlib"""
        # Filter staff with ratings
        rated_staff = [s for s in staff_list if s['total_ratings'] > 0]
        
        if not rated_staff:
            # Return empty chart
            fig, ax = plt.subplots(figsize=(10, 6), facecolor='#2F3136')
            ax.set_facecolor('#2F3136')
            ax.text(0.5, 0.5, 'Aucune évaluation disponible', ha='center', va='center', 
                    transform=ax.transAxes, color='white')
            ax.set_title('Évaluations des Membres du Staff', color='white')
            buf = io.BytesIO()
            plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136')
            buf.seek(0)
            plt.close()
            return buf

        # Sort by average rating
        rated_staff.sort(key=lambda x: x['average_rating'], reverse=True)
        
        # Prepare data
        names = [s['name'][:15] + '...' if len(s['name']) > 15 else s['name'] for s in rated_staff]
        ratings = [s['average_rating'] for s in rated_staff]
        counts = [s['total_ratings'] for s in rated_staff]
        
        # Create figure
        fig, ax = plt.subplots(figsize=(12, 8), facecolor='#2F3136')
        fig.patch.set_facecolor('#2F3136')
        ax.set_facecolor('#2F3136')
        
        # Create bars
        bars = ax.bar(range(len(ratings)), ratings, color=['#57F287' if r >= 4.5 else '#FEE75C' if r >= 3.5 else '#FAA61A' if r >= 2.5 else '#ED4245' for r in ratings])
        
        # Customize
        ax.set_xticks(range(len(names)))
        ax.set_xticklabels(names, rotation=45, ha='right', color='white')
        ax.set_ylabel('Note moyenne', color='white')
        ax.set_title('Évaluations des Membres du Staff', color='white', fontsize=16)
        ax.tick_params(colors='white')
        ax.grid(True, alpha=0.3, color='gray')
        
        # Add value labels on bars
        for i, (bar, rating, count) in enumerate(zip(bars, ratings, counts)):
            ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.05,
                   f'{rating:.1f}⭐\n({count})', ha='center', va='bottom', color='white', fontsize=8)
        
        # Set y-axis limits
        ax.set_ylim(0, 5.2)
        
        # Adjust layout
        plt.tight_layout()
        
        # Save to buffer
        buf = io.BytesIO()
        plt.savefig(buf, format='png', bbox_inches='tight', facecolor='#2F3136')
        buf.seek(0)
        plt.close()
        return buf


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