import discord
from discord.ext import commands
import asyncio
import yt_dlp
import os
from collections import deque

# Kontrola FFmpeg
try:
    import subprocess
    subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
    FFMPEG_AVAILABLE = True
except (subprocess.CalledProcessError, FileNotFoundError):
    FFMPEG_AVAILABLE = False
    print("⚠️ FFmpeg není nainstalován! Music commands nebudou fungovat.")

# Nastavení pro yt-dlp
ytdl_format_options = {
    'format': 'bestaudio/best',
    'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
    'restrictfilenames': True,
    'noplaylist': True,
    'nocheckcertificate': True,
    'ignoreerrors': False,
    'logtostderr': False,
    'quiet': True,
    'no_warnings': True,
    'default_search': 'auto',
    'source_address': '0.0.0.0',
    'extract_flat': False
}

ffmpeg_options = {
    'options': '-vn'
}

ytdl = yt_dlp.YoutubeDL(ytdl_format_options)

class YTDLSource(discord.PCMVolumeTransformer):
    def __init__(self, source, *, data, volume=0.5):
        super().__init__(source, volume)
        self.data = data
        self.title = data.get('title')
        self.url = data.get('url')
        self.duration = data.get('duration')

    @classmethod
    async def from_url(cls, url, *, loop=None, stream=False):
        loop = loop or asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))

        if 'entries' in data:
            # Vezmi první položku z playlistu
            data = data['entries'][0]

        filename = data['url'] if stream else ytdl.prepare_filename(data)
        return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)

class MusicQueue:
    def __init__(self):
        self.queue = deque()
        self.current = None
        self.np = None  # Now playing message

    def add(self, item):
        self.queue.append(item)

    def get_next(self):
        if self.queue:
            return self.queue.popleft()
        return None

    def clear(self):
        self.queue.clear()

    def shuffle(self):
        import random
        temp_list = list(self.queue)
        random.shuffle(temp_list)
        self.queue = deque(temp_list)

class Music(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.music_queues = {}  # Guild-specific queues

    def get_queue(self, guild_id):
        if guild_id not in self.music_queues:
            self.music_queues[guild_id] = MusicQueue()
        return self.music_queues[guild_id]

    async def play_next(self, ctx):
        """Přehraje další skladbu z fronty"""
        queue = self.get_queue(ctx.guild.id)
        
        if queue.queue:
            next_song = queue.get_next()
            queue.current = next_song
            
            try:
                player = await YTDLSource.from_url(next_song['url'], loop=self.bot.loop, stream=True)
                ctx.voice_client.play(player, after=lambda e: asyncio.run_coroutine_threadsafe(self.play_next(ctx), self.bot.loop))
                
                embed = discord.Embed(
                    title="🎵 Právě hraje",
                    description=f"**{player.title}**",
                    color=0x5865F2  # Změněno na Discord modrou
                )
                if player.duration:
                    minutes = player.duration // 60
                    seconds = player.duration % 60
                    embed.add_field(name="⏱️ Délka", value=f"{minutes}:{seconds:02d}", inline=True)
                
                await ctx.send(embed=embed)
                
            except Exception as e:
                await ctx.send(f"❌ Chyba při přehrávání: {e}")
                await self.play_next(ctx)

    @commands.command(name='join', aliases=['connect'])
    async def join(self, ctx):
        """Připojí bota do hlasového kanálu"""
        if not ctx.author.voice:
            await ctx.send("❌ Nejsi připojen k hlasovému kanálu!")
            return

        channel = ctx.author.voice.channel
        
        if ctx.voice_client is not None:
            await ctx.voice_client.move_to(channel)
        else:
            await channel.connect()

        embed = discord.Embed(
            title="✅ Připojen",
            description=f"Připojen k **{channel.name}**",
            color=0x5865F2  # Změněno na Discord modrou
        )
        await ctx.send(embed=embed)

    @commands.command(name='play', aliases=['p'])
    async def play(self, ctx, *, query):
        """Přehraje hudbu z YouTube"""
        async with ctx.typing():
            if not ctx.voice_client:
                await self.join(ctx)

            try:
                # Hledání na YouTube
                player = await YTDLSource.from_url(query, loop=self.bot.loop, stream=True)
                queue = self.get_queue(ctx.guild.id)

                if ctx.voice_client.is_playing():
                    # Přidej do fronty
                    queue.add({
                        'url': query,
                        'title': player.title,
                        'requester': ctx.author
                    })
                    
                    embed = discord.Embed(
                        title="📝 Přidáno do fronty",
                        description=f"**{player.title}**",
                        color=0x5865F2  # Změněno na Discord modrou
                    )
                    embed.add_field(name="👤 Požadavek od", value=ctx.author.mention, inline=True)
                    embed.add_field(name="📊 Pozice ve frontě", value=len(queue.queue), inline=True)
                    await ctx.send(embed=embed)
                else:
                    # Přehraj ihned
                    queue.current = {
                        'url': query,
                        'title': player.title,
                        'requester': ctx.author
                    }
                    
                    ctx.voice_client.play(player, after=lambda e: asyncio.run_coroutine_threadsafe(self.play_next(ctx), self.bot.loop))
                    
                    embed = discord.Embed(
                        title="🎵 Právě hraje",
                        description=f"**{player.title}**",
                        color=0x5865F2  # Změněno na Discord modrou
                    )
                    embed.add_field(name="👤 Požadavek od", value=ctx.author.mention, inline=True)
                    if player.duration:
                        minutes = player.duration // 60
                        seconds = player.duration % 60
                        embed.add_field(name="⏱️ Délka", value=f"{minutes}:{seconds:02d}", inline=True)
                    
                    await ctx.send(embed=embed)

            except Exception as e:
                await ctx.send(f"❌ Chyba při hledání: {e}")

    @commands.command(name='pause')
    async def pause(self, ctx):
        """Pozastaví přehrávání"""
        if ctx.voice_client and ctx.voice_client.is_playing():
            ctx.voice_client.pause()
            embed = discord.Embed(title="⏸️ Pozastaveno", color=0x5865F2)
            await ctx.send(embed=embed)
        else:
            await ctx.send("❌ Nic se nepřehrává!")

    @commands.command(name='resume')
    async def resume(self, ctx):
        """Obnoví přehrávání"""
        if ctx.voice_client and ctx.voice_client.is_paused():
            ctx.voice_client.resume()
            embed = discord.Embed(title="▶️ Obnoveno", color=0x5865F2)
            await ctx.send(embed=embed)
        else:
            await ctx.send("❌ Přehrávání není pozastaveno!")

    @commands.command(name='skip', aliases=['next'])
    async def skip(self, ctx):
        """Přeskočí aktuální skladbu"""
        if ctx.voice_client and ctx.voice_client.is_playing():
            ctx.voice_client.stop()
            embed = discord.Embed(title="⏭️ Přeskočeno", color=0x5865F2)
            await ctx.send(embed=embed)
        else:
            await ctx.send("❌ Nic se nepřehrává!")

    @commands.command(name='queue', aliases=['q'])
    async def show_queue(self, ctx):
        """Zobrazí frontu skladeb"""
        queue = self.get_queue(ctx.guild.id)
        
        if not queue.queue and not queue.current:
            await ctx.send("❌ Fronta je prázdná!")
            return

        embed = discord.Embed(title="🎵 Fronta skladeb", color=0x5865F2)
        
        if queue.current:
            embed.add_field(
                name="▶️ Právě hraje",
                value=f"**{queue.current['title']}**\nPožadavek od: {queue.current['requester'].mention}",
                inline=False
            )

        if queue.queue:
            queue_list = []
            for i, song in enumerate(list(queue.queue)[:10], 1):  # Max 10 skladeb
                queue_list.append(f"`{i}.` **{song['title']}** - {song['requester'].mention}")
            
            embed.add_field(
                name="📝 Následující skladby",
                value="\n".join(queue_list),
                inline=False
            )
            
            if len(queue.queue) > 10:
                embed.add_field(name="ℹ️", value=f"... a {len(queue.queue) - 10} dalších skladeb", inline=False)

        await ctx.send(embed=embed)

    @commands.command(name='clearqueue', aliases=['cq'])  # Změněno z 'clear'
    async def clear_queue(self, ctx):
        """Vymaže frontu"""
        queue = self.get_queue(ctx.guild.id)
        queue.clear()
        embed = discord.Embed(title="🗑️ Fronta vymazána", color=0x5865F2)
        await ctx.send(embed=embed)

    @commands.command(name='shuffle')
    async def shuffle_queue(self, ctx):
        """Zamíchá frontu"""
        queue = self.get_queue(ctx.guild.id)
        if not queue.queue:
            await ctx.send("❌ Fronta je prázdná!")
            return
        
        queue.shuffle()
        embed = discord.Embed(title="🔀 Fronta zamíchána", color=0x5865F2)
        await ctx.send(embed=embed)

    @commands.command(name='volume', aliases=['vol'])
    async def volume(self, ctx, volume: int = None):
        """Nastaví hlasitost (0-100)"""
        if volume is None:
            if ctx.voice_client and ctx.voice_client.source:
                current_vol = int(ctx.voice_client.source.volume * 100)
                await ctx.send(f"🔊 Aktuální hlasitost: {current_vol}%")
            else:
                await ctx.send("❌ Nic se nepřehrává!")
            return

        if not 0 <= volume <= 100:
            await ctx.send("❌ Hlasitost musí být mezi 0-100!")
            return

        if ctx.voice_client and ctx.voice_client.source:
            ctx.voice_client.source.volume = volume / 100
            embed = discord.Embed(
                title="🔊 Hlasitost změněna",
                description=f"Nastaveno na {volume}%",
                color=0x5865F2  # Změněno na Discord modrou
            )
            await ctx.send(embed=embed)
        else:
            await ctx.send("❌ Nic se nepřehrává!")

    @commands.command(name='disconnect', aliases=['leave', 'dc'])
    async def disconnect(self, ctx):
        """Odpojí bota z hlasového kanálu"""
        if ctx.voice_client:
            queue = self.get_queue(ctx.guild.id)
            queue.clear()
            await ctx.voice_client.disconnect()
            embed = discord.Embed(title="👋 Odpojen", color=0x5865F2)
            await ctx.send(embed=embed)
        else:
            await ctx.send("❌ Nejsem připojen k hlasovému kanálu!")

    @commands.command(name='nowplaying', aliases=['np'])
    async def now_playing(self, ctx):
        """Zobrazí aktuálně přehrávanou skladbu"""
        queue = self.get_queue(ctx.guild.id)
        
        if not queue.current:
            await ctx.send("❌ Nic se nepřehrává!")
            return

        embed = discord.Embed(
            title="🎵 Právě hraje",
            description=f"**{queue.current['title']}**",
            color=0x5865F2  # Změněno na Discord modrou
        )
        embed.add_field(name="👤 Požadavek od", value=queue.current['requester'].mention, inline=True)
        
        if ctx.voice_client and ctx.voice_client.source:
            volume = int(ctx.voice_client.source.volume * 100)
            embed.add_field(name="🔊 Hlasitost", value=f"{volume}%", inline=True)

        await ctx.send(embed=embed)

async def setup(bot):
    await bot.add_cog(Music(bot))
