"""
Ticket Formatters
=================
Beautiful embed and message formatters for the ticket system.
"""
from datetime import datetime
from typing import Optional, List, Dict, Any
from disnake import Embed, Color, User, Member, Role

from ..data.models import (
    TicketData,
    TicketCategory,
    TicketStats,
    GuildTicketConfig,
    TicketStatus,
    Priority
)


class TicketEmbedFormatter:
    """
    Creates beautiful, consistent embeds for the ticket system.
    
    Features:
    - Color-coded by priority
    - Consistent styling
    - Rich information display
    - Translatable text
    """
    
    # Priority colors
    PRIORITY_COLORS = {
        Priority.LOW: Color.green(),
        Priority.NORMAL: Color.blue(),
        Priority.HIGH: Color.orange(),
        Priority.URGENT: Color.red()
    }
    
    # Status emojis
    STATUS_EMOJIS = {
        TicketStatus.OPEN: "🟢",
        TicketStatus.CLAIMED: "🟡",
        TicketStatus.CLOSED: "🔴",
        TicketStatus.ARCHIVED: "⚫"
    }
    
    # Priority emojis
    PRIORITY_EMOJIS = {
        Priority.LOW: "🟢",
        Priority.NORMAL: "🔵",
        Priority.HIGH: "🟠",
        Priority.URGENT: "🔴"
    }
    
    @classmethod
    def get_priority_color(cls, priority: Priority) -> Color:
        """Get embed color based on priority"""
        return cls.PRIORITY_COLORS.get(priority, Color.blue())
    
    @classmethod
    def format_status(cls, status: TicketStatus) -> str:
        """Get formatted status with emoji"""
        emoji = cls.STATUS_EMOJIS.get(status, "⚪")
        status_names = {
            TicketStatus.OPEN: "Ouvert",
            TicketStatus.CLAIMED: "Réclamé",
            TicketStatus.CLOSED: "Fermé",
            TicketStatus.ARCHIVED: "Archivé"
        }
        return f"{emoji} {status_names.get(status, status.value)}"
    
    @classmethod
    def format_priority(cls, priority: Priority) -> str:
        """Get formatted priority with emoji"""
        emoji = cls.PRIORITY_EMOJIS.get(priority, "⚪")
        priority_names = {
            Priority.LOW: "Basse",
            Priority.NORMAL: "Normale",
            Priority.HIGH: "Haute",
            Priority.URGENT: "Urgente"
        }
        return f"{emoji} {priority_names.get(priority, priority.value)}"
    
    # --- Ticket Creation Embeds ---
    
    @classmethod
    def ticket_created(
        cls,
        ticket: TicketData,
        user: User,
        category: Optional[TicketCategory] = None,
        guild_name: str = "Serveur"
    ) -> Embed:
        """Embed for when a ticket is created"""
        embed = Embed(
            title="🎫 Nouveau Ticket Créé",
            description=category.welcome_message if category else "Merci d'avoir créé un ticket. Notre équipe va vous répondre sous peu.",
            color=cls.get_priority_color(ticket.priority),
            timestamp=datetime.now()
        )
        
        embed.set_author(name=user.display_name, icon_url=user.display_avatar.url)
        
        # Add fields
        embed.add_field(name="📌 Ticket ID", value=f"`{ticket.channel_id}`", inline=True)
        embed.add_field(name="👤 Utilisateur", value=user.mention, inline=True)
        embed.add_field(name="📁 Catégorie", value=category.name if category else ticket.category_id, inline=True)
        embed.add_field(name="⚡ Priorité", value=cls.format_priority(ticket.priority), inline=True)
        
        if ticket.reason:
            embed.add_field(name="📝 Raison", value=ticket.reason, inline=False)
        
        embed.set_footer(text=f"ID: {ticket.channel_id} | {guild_name}")
        
        return embed
    
    @classmethod
    def ticket_closed(
        cls,
        ticket: TicketData,
        closed_by: User,
        duration_minutes: float,
        reason: Optional[str] = None
    ) -> Embed:
        """Embed for when a ticket is closed"""
        embed = Embed(
            title="🔴 Ticket Fermé",
            description=f"Ce ticket a été fermé par {closed_by.mention}",
            color=Color.red(),
            timestamp=datetime.now()
        )
        
        embed.add_field(name="👤 Fermé par", value=closed_by.mention, inline=True)
        embed.add_field(name="⏱️ Durée", value=cls._format_duration(duration_minutes), inline=True)
        embed.add_field(name="📊 Statut", value=cls.format_status(ticket.status), inline=True)
        
        if reason:
            embed.add_field(name="📝 Raison de fermeture", value=reason, inline=False)
        
        return embed
    
    @classmethod
    def ticket_reopened(cls, ticket: TicketData, reopened_by: User) -> Embed:
        """Embed for when a ticket is reopened"""
        embed = Embed(
            title="🟢 Ticket Rouvert",
            description=f"Ce ticket a été rouvert par {reopened_by.mention}",
            color=Color.green(),
            timestamp=datetime.now()
        )
        
        embed.add_field(name="👤 Rouvert par", value=reopened_by.mention, inline=True)
        embed.add_field(name="📊 Statut", value=cls.format_status(ticket.status), inline=True)
        
        return embed
    
    @classmethod
    def ticket_claimed(cls, ticket: TicketData, claimed_by: User) -> Embed:
        """Embed for when a ticket is claimed"""
        embed = Embed(
            title="🟡 Ticket Réclamé",
            description=f"Ce ticket a été réclamé par {claimed_by.mention}",
            color=Color.gold(),
            timestamp=datetime.now()
        )
        
        embed.add_field(name="👤 Réclamé par", value=claimed_by.mention, inline=True)
        embed.add_field(name="📊 Statut", value=cls.format_status(ticket.status), inline=True)
        
        return embed
    
    @classmethod
    def ticket_unclaimed(cls, ticket: TicketData, unclaimed_by: User) -> Embed:
        """Embed for when a ticket claim is removed"""
        embed = Embed(
            title="🟠 Ticket Non Réclamé",
            description=f"Le ticket n'est plus réclamé par {unclaimed_by.mention}",
            color=Color.orange(),
            timestamp=datetime.now()
        )
        
        return embed
    
    # --- Panel Embeds ---
    
    @classmethod
    def panel_embed(
        cls,
        config: GuildTicketConfig,
        guild_name: str
    ) -> Embed:
        """Embed for the ticket creation panel"""
        embed = Embed(
            title="🎫 Support - Créer un Ticket",
            description="Cliquez sur le bouton ci-dessous pour créer un ticket. Notre équipe vous répondra dans les plus brefs délais.",
            color=Color.blue(),
            timestamp=datetime.now()
        )
        
        # Add categories
        if config.categories:
            categories_text = "\n".join(
                f"{cat.emoji} **{cat.name}**\n{cat.description}"
                for cat in config.categories
            )
            embed.add_field(name="📁 Catégories disponibles", value=categories_text, inline=False)
        
        embed.set_footer(text=f"ID: {config.guild_id} | {guild_name}")
        
        return embed
    
    @classmethod
    def category_select_embed(cls, categories: List[TicketCategory]) -> Embed:
        """Embed shown when selecting a category"""
        embed = Embed(
            title="📁 Choisir une catégorie",
            description="Sélectionnez la catégorie qui correspond le mieux à votre demande:",
            color=Color.blue(),
            timestamp=datetime.now()
        )
        
        for cat in categories:
            embed.add_field(
                name=f"{cat.emoji} {cat.name}",
                value=cat.description or "Aucune description",
                inline=False
            )
        
        return embed
    
    # --- Admin Embeds ---
    
    @classmethod
    def ticket_list_embed(
        cls,
        tickets: List[TicketData],
        user: Optional[User] = None
    ) -> Embed:
        """Embed showing a list of tickets"""
        embed = Embed(
            title="📋 Liste des Tickets",
            description=f"Nombre de tickets: **{len(tickets)}**",
            color=Color.blue()
        )
        
        if user:
            embed.set_author(name=f"Tickets de {user.display_name}", icon_url=user.display_avatar.url)
        
        # Group by status
        by_status = {}
        for ticket in tickets:
            status = cls.format_status(ticket.status)
            by_status.setdefault(status, []).append(ticket)
        
        for status, status_tickets in by_status.items():
            ticket_list = "\n".join(
                f"`{t.channel_id}` - {t.category_id} ({cls.format_priority(t.priority)})"
                for t in status_tickets[:10]  # Limit to 10 per status
            )
            if len(status_tickets) > 10:
                ticket_list += f"\n... et {len(status_tickets) - 10} autres"
            
            embed.add_field(name=status, value=ticket_list or "Aucun", inline=False)
        
        return embed
    
    @classmethod
    def stats_embed(cls, stats: TicketStats, guild_name: str) -> Embed:
        """Embed showing ticket statistics"""
        embed = Embed(
            title="📊 Statistiques des Tickets",
            color=Color.blue(),
            timestamp=datetime.now()
        )
        
        embed.set_author(name=guild_name)
        
        # Main stats
        embed.add_field(name="📝 Total", value=str(stats.total_tickets), inline=True)
        embed.add_field(name="🟢 Ouverts", value=str(stats.open_tickets), inline=True)
        embed.add_field(name="🔴 Fermés", value=str(stats.closed_tickets), inline=True)
        
        embed.add_field(name="⏱️ Durée Moyenne", value=cls._format_duration(stats.average_duration_minutes), inline=True)
        embed.add_field(name="⭐ Note Moyenne", value=f"{stats.average_rating:.1f}/5" if stats.average_rating else "N/A", inline=True)
        
        # By category
        if stats.tickets_by_category:
            cat_text = "\n".join(f"{cat}: **{count}**" for cat, count in stats.tickets_by_category.items())
            embed.add_field(name="📁 Par Catégorie", value=cat_text, inline=False)
        
        # By priority
        if stats.tickets_by_priority:
            priority_text = "\n".join(f"{prio}: **{count}**" for prio, count in stats.tickets_by_priority.items())
            embed.add_field(name="⚡ Par Priorité", value=priority_text, inline=False)
        
        return embed
    
    @classmethod
    def ticket_info_embed(
        cls,
        ticket: TicketData,
        user: Optional[User] = None,
        category: Optional[TicketCategory] = None
    ) -> Embed:
        """Embed showing detailed ticket information"""
        embed = Embed(
            title=f"🎫 Informations du Ticket",
            color=cls.get_priority_color(ticket.priority),
            timestamp=datetime.now()
        )
        
        if user:
            embed.set_author(name=user.display_name, icon_url=user.display_avatar.url)
        
        embed.add_field(name="📌 ID", value=f"`{ticket.channel_id}`", inline=True)
        embed.add_field(name="📊 Statut", value=cls.format_status(ticket.status), inline=True)
        embed.add_field(name="⚡ Priorité", value=cls.format_priority(ticket.priority), inline=True)
        embed.add_field(name="📁 Catégorie", value=category.name if category else ticket.category_id, inline=True)
        
        embed.add_field(name="📅 Créé le", value=ticket.created_at.strftime("%d/%m/%Y à %H:%M"), inline=True)
        
        if ticket.closed_at:
            embed.add_field(name="🔴 Fermé le", value=ticket.closed_at.strftime("%d/%m/%Y à %H:%M"), inline=True)
        
        if ticket.claimed_by:
            embed.add_field(name="👤 Réclamé par", value=f"<@{ticket.claimed_by}>", inline=True)
        
        if ticket.reason:
            embed.add_field(name="📝 Raison", value=ticket.reason, inline=False)
        
        if ticket.duration_minutes:
            embed.add_field(name="⏱️ Durée", value=cls._format_duration(ticket.duration_minutes), inline=True)
        
        if ticket.rating:
            stars = "⭐" * ticket.rating
            embed.add_field(name="⭐ Note", value=f"{stars} ({ticket.rating}/5)", inline=True)
        
        return embed
    
    # --- Survey Embeds ---
    
    @classmethod
    def survey_embed(cls) -> Embed:
        """Embed for satisfaction survey"""
        embed = Embed(
            title="⭐ Évaluation du Support",
            description="Merci d'avoir utilisé notre système de tickets! "
                       "Pour améliorer nos services, merci de noter votre expérience.",
            color=Color.gold(),
            timestamp=datetime.now()
        )
        
        embed.add_field(name="1 ⭐", value="Très insatisfait", inline=True)
        embed.add_field(name="3 ⭐", value="Neutre", inline=True)
        embed.add_field(name="5 ⭐", value="Très satisfait", inline=True)
        
        return embed
    
    @classmethod
    def survey_thanks_embed(cls, rating: int) -> Embed:
        """Embed shown after submitting a survey"""
        stars = "⭐" * rating
        embed = Embed(
            title="Merci pour votre évaluation!",
            description=f"Vous avez attribué: {stars}",
            color=Color.green()
        )
        return embed
    
    # --- Helper Methods ---
    
    @staticmethod
    def _format_duration(minutes: float) -> str:
        """Format duration in minutes to human-readable string"""
        if minutes < 1:
            return f"{minutes * 60:.0f}s"
        elif minutes < 60:
            return f"{minutes:.0f}min"
        elif minutes < 1440:
            hours = minutes / 60
            return f"{hours:.1f}h"
        else:
            days = minutes / 1440
            return f"{days:.1f}j"


class TicketMessageFormatter:
    """Formats regular messages for the ticket system"""
    
    @staticmethod
    def welcome_message(
        user: User,
        category: TicketCategory
    ) -> str:
        """Welcome message when entering a ticket"""
        return (
            f"👋 Bienvenue {user.mention} dans votre ticket **{category.name}**!\n\n"
            f"{category.welcome_message}\n\n"
            f"Un membre de notre équipe va vous répondre sous peu."
        )
    
    @staticmethod
    def staff_notification(
        claimed_by: User,
        ticket_channel_mention: str
    ) -> str:
        """Notification when a ticket is claimed"""
        return (
            f"🟡 Le ticket {ticket_channel_mention} a été réclamé par {claimed_by.mention}"
        )
    
    @staticmethod
    def ticket_closed_notification(
        closed_by: User,
        reason: Optional[str] = None
    ) -> str:
        """Notification when a ticket is closed"""
        msg = f"🔴 Ce ticket a été fermé par {closed_by.mention}"
        if reason:
            msg += f"\n📝 Raison: {reason}"
        return msg
    
    @staticmethod
    def auto_close_warning(
        days_remaining: int,
        ticket_channel_mention: str
    ) -> str:
        """Warning before auto-closing a ticket"""
        return (
            f"⚠️ Ce ticket {ticket_channel_mention} sera fermé automatiquement "
            f"dans **{days_remaining} jour(s)** en raison de son inactivity."
        )
    
    @staticmethod
    def transcript_saved(filepath: str) -> str:
        """Message when transcript is saved"""
        return f"📄 Transcript sauvegardé: `{filepath}`"
    
    @staticmethod
    def no_permission(action: str) -> str:
        """Message when user has no permission"""
        return f"❌ Vous n'avez pas la permission de {action}"
    
    @staticmethod
    def ticket_limit_reached(limit: int) -> str:
        """Message when user has reached ticket limit"""
        return f"❌ Vous avez atteint la limite de {limit} tickets ouverts"
    
    @staticmethod
    def already_has_ticket(channel_mention: str) -> str:
        """Message when user already has a ticket"""
        return f"❌ Vous avez déjà un ticket ouvert: {channel_mention}"

