import asyncio
import logging
import random
import re
from datetime import datetime
from sys import platform

import discord
import eyed3
from discord.ext import commands, tasks

import music_functions
from ai_functions import handle_response
from communication_subroutine import PREPPED_TRACKS
from constants import MESSAGE_TABLE_MUZYKA, MUZYKA, SEPARATOR_FILE_PATH
from other_functions import get_stats


class MusicModule(commands.Cog):
    def __init__(self, bot, logger_name):
        self.bot = bot
        self.logger = logging.getLogger(logger_name)

    @commands.hybrid_command(
        name="krecimy_pornola",
        description="Wiadomo co, dla kogo i po co",
    )
    @commands.has_any_role('Legenda', 'Jarl', 'Thane' , 'Bartender')
    async def krecimy_pornola(self, ctx):
        """
        Download a music number from youtube.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. It allows the command to interact
        with the Discord API and
        """
        await ctx.send("Dej mnie chwilkę")
        self.logger.info("Pornol")
        async with ctx.typing():
            # wyciagnij linka z kontekstu
            content = ctx.message.content.split()
            for item_yt in content:
                if re.match("http.*", item_yt):
                    sciezka, files = await music_functions.get_file(
                        ctx, "Pornol", item_yt
                    )
                    if files:
                        self.logger.info("Pornol udany")
                        await ctx.send(
                            f"Jest w tajnym archiwum pod adresem{sciezka})"
                        )

    @commands.hybrid_command(
        name="co_na_plejliscie_wariacie",
        description="Wyswietl kawalki ktore sa na pocztku list radia",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')

    async def co_na_plejliscie_wariacie(self, ctx):
        """
        Download a music number from youtube.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. It allows the command to interact
        with the Discord API and
        """
        await ctx.send("Dej mnie chwilkę")
        async with ctx.typing():
            self.logger.info("plejlista")
            self.logger.info(PREPPED_TRACKS)
            await ctx.send(
                f"Didżej Hammer i jego sztuczna inteligencja (||he he||) prezentują: \n- obecnie grany jest {(PREPPED_TRACKS['now_playing']).rstrip()} (wg metadanych: {PREPPED_TRACKS['meta']}) \n- następny będzie{(PREPPED_TRACKS['next']).rstrip()} \n- na liście priorytetowej {(PREPPED_TRACKS['priority']).rstrip()} \n- na liście hitów obecnie czeka kawałek {(PREPPED_TRACKS['hit']).rstrip()} \n- na liście wszystkich kawałków {(PREPPED_TRACKS['all']).rstrip()} \n- najświeższym zamówieniem od słuchaczy jest {(PREPPED_TRACKS['requests']).rstrip()} \nZ kolei jingiel to: {(PREPPED_TRACKS['jingles']).rstrip()}"
            )

    @tasks.loop(seconds=1)
    async def check_music(self):
        """
        This Python function continuously checks for music playback in a voice client and plays music if
        conditions are met.
        """
        if self.bot.voice_clients:
            voice_client = self.bot.voice_clients[0]
            if (
                voice_client
                and voice_client.is_connected()
                and not voice_client.is_playing()
                and not voice_client.is_paused()
            ):
                await self.play(MUZYKA["ctx"], MUZYKA["requester"])
                await asyncio.sleep(2)

    @commands.hybrid_command(
        name="dej_co_z_jutuba",
        description="Podaj link do youtube - sciagnie i doda muzyke",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def dej_co_z_jutuba(self, ctx):
        """
        Download a music number from youtube.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. It allows the command to interact
        with the Discord API and
        """
        await ctx.send("Dej mnie chwilkę")
        self.logger.info("Jutub")
        async with ctx.typing():
            # wyciagnij linka z kontekstu
            content = ctx.message.content.split()
            for item_yt in content:
                if re.match("http.*", item_yt):
                    _, files = await music_functions.get_file(ctx, "Youtube", item_yt)
                    if files:
                        for file_iter in files:
                            global MUZYKA  # pylint: disable=global-variable-not-assigned
                            MUZYKA["queue"].insert(0, file_iter)
                            music_functions.MUSIC_FILE_LIST.update_file_list(file_iter)
                            MUZYKA["requester"].insert(0, ctx.author)
                            await ctx.send(f"Dodałem do listy {file_iter}")
                        self.logger.info("Jutub udany")

    @commands.hybrid_command(
        name="dej_co_ze_spotifaja",
        description="Podaj link do spotify - sciagnie i doda muzyke",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def dej_co_ze_spotifaja(self, ctx):
        """
        Get a playlist or a music number from Spotify.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in all
        Discord.py commands
        """
        self.logger.info("Spotifaj")
        await ctx.send("Dej mnie chwilkę")
        async with ctx.typing():
            # wyciagnij linka z kontekstu
            content = ctx.message.content.split()
            for item in content:
                if re.match("http.*", item):
                    dir_path, files = await music_functions.get_file(
                        ctx, "Spotify", item
                    )
                    if platform == "win32":
                        separator = "\\"
                    else:
                        separator = "/"
                    for file in files:
                        file_path = (
                            dir_path
                            + separator
                            + file["artist"]
                            + " - "
                            + file["name"]
                            + ".mp3"
                        )
                        global MUZYKA  # pylint: disable=global-variable-not-assigned
                        MUZYKA["queue"].insert(
                            0,
                            dir_path
                            + separator
                            + file["artist"]
                            + " - "
                            + file["name"]
                            + ".mp3",
                        )
                        MUZYKA["requester"].insert(0, ctx.author)
                        music_functions.MUSIC_FILE_LIST.update_file_list(file_path)
                        await ctx.send(
                            f"Dodałem do listy {dir_path}{file['artist']} -  + {file['name']}.mp3"
                        )
                        self.logger.info("Spotifaj udany")

    # MUSIC BOT PART
    @commands.hybrid_command(
        name="cisza",
        description="Wyłącza muzykę i czyści plejliste.",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def cisza(self, ctx):
        """
        Stop playback of the music and clear the queue.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in all
        Discord.py commands
        """
        self.logger.info("Stop")
        global MUZYKA  # pylint: disable=global-variable-not-assigned
        MUZYKA["ctx"] = None
        voice_client = self.bot.voice_clients[0]
        self.check_music.stop()
        if voice_client.is_connected():
            await self.disconnect(ctx=ctx)
            while MUZYKA["queue"]:
                MUZYKA["queue"].pop()
                MUZYKA["requester"].pop()
                self.logger.info("Stop completed")

    @commands.hybrid_command(
        name="dalej",
        description="Przerzuca na następny kawałek",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def dalej(self, ctx):
        """
        Play next track in queue.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which a command is being executed, including information such as the
        message, the channel, the server, and the user who invoked the command. The context object is used
        to access and manipulate this
        """
        if ctx:
            self.logger.info("Ctx defined for dalej")
        self.logger.info("Next")
        voice_client = self.bot.voice_clients[0]
        if voice_client.is_connected():
            voice_client.stop()
            self.logger.info("Next completed")

    @commands.hybrid_command(
        name="daj_mi_chwile",
        description="Pauzuje",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def daj_mi_chwile(self, ctx):
        """
        Pause music playback.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in most
        Discord.py commands and is
        """
        if ctx:
            self.logger.info("Ctx defined for pause")

        self.logger.info("Pause")
        voice_client = self.bot.voice_clients[0]
        if voice_client.is_connected():
            voice_client.pause()
            self.logger.info("Pause completed")

    @commands.hybrid_command(
        name="graj_dalej",
        description="Odpauzowuje",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def graj_dalej(self, ctx):
        """
        Unpause music and continue playback.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in all
        Discord.py commands
        """
        if ctx:
            self.logger.info("Ctx defined for graj_dalej")
        self.logger.info("Unpause")
        voice_client = self.bot.voice_clients[0]
        if voice_client.is_paused():
            voice_client.resume()
            self.logger.info("Unpause completed")

    @commands.hybrid_command(
        name="zagraj_mi_kawalek",
        description="Wyszukuje w bibliotece muzycznej Hammera kawałek który ma zostać zagrany",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def zagraj_mi_kawalek(self, ctx):
        """
        Play a song or music piece in response to a command
        triggered by a user in a Discord chat context.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        contains information about the context in which the command was invoked, such as the message, the
        channel, the server, and the user who invoked the command. This information can be used to perform
        various actions, such
        """
        async with ctx.typing():
            search_time_glob = datetime.now()
            self.logger.info("Zaczynam szukać timestamp %s", datetime.now())
            file = await self.wyszukaj(ctx=ctx)
            self.logger.info(
                "Koniec szukania(timestamp %s zajęło %s",
                datetime.now(),
                datetime.now() - search_time_glob,
            )

            if file:
                for plik in file:
                    global MUZYKA  # pylint: disable=global-variable-not-assigned
                    MUZYKA["queue"].insert(0, plik[1])
                    MUZYKA["requester"].insert(0, ctx.author)
                    metadata = eyed3.load(plik[1])
                    reply = (
                        "Dodałem do playlisty {plik[1]} z prywatnej kolekcji Hammera."
                    )
                    if metadata.tag.title:
                        reply = f"Dodałem do playlisty kawalek {metadata.tag.title}"
                    if metadata.tag.artist:
                        reply += f" wykonawcy {metadata.tag.artist}"
                    if metadata.tag.album:
                        reply += f" z albumu {metadata.tag.album}"
                    reply += (
                        " z prywatnej kolekcji Hammera i na Twoją specjalną rpośbę."
                    )
                    await ctx.send(reply)
            else:
                await ctx.send(
                    "Obawiam się że nie mogę nic znaleźć u siebie. Spróbuj komendy '$dej_co_ze_spotifaja' jeśli masz link"
                )

    @commands.hybrid_command(
        name="zrob_mi_plejliste",
        description="Generuje playliste - param1 - dlugosc, potem slowa wyszukiwania",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def zrob_mi_plejliste(self, ctx):
        """
        Generate a playlist in queue. First word in this command shall be int defining length of the playlist.
        Rest of the line are search terms.

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in all
        Discord.py commands
        """
        reply = "Wygenerowana plejlista:\n"
        async with ctx.typing():
            self.logger.info("Zaczynam szukać timestamp %s", datetime.now())
            search_time_glob = datetime.now()

            dlugosc_playlisty = ctx.message.content.split()[1]
            file = await music_functions.wyszukaj(ctx=ctx, how_many=dlugosc_playlisty)
            self.logger.info(
                "Koniec szukania(timestamp %s zajęło %s",
                datetime.now(),
                datetime.now() - search_time_glob,
            )
            index = 1
            if file:
                for plik in file:
                    if plik[1]:
                        self.logger.info(plik)
                        global MUZYKA  # pylint: disable=global-variable-not-assigned
                        MUZYKA["queue"].insert(0, plik[1])
                        MUZYKA["requester"].insert(0, ctx.author)
                        metadata = eyed3.load(plik[1])
                        if metadata and metadata.tag:
                            if metadata.tag.title:
                                reply += f"{index} {metadata.tag.title}"
                            else:
                                reply += (
                                    f"{index}. {plik[1]} z prywatnej kolekcji Hammera."
                                )

                            if metadata.tag.artist:
                                reply += f" wykonawcy {metadata.tag.artist}"
                            if metadata.tag.album:
                                reply += f" z albumu {metadata.tag.album}"
                            if metadata.tag.title:
                                reply += " z prywatnej kolekcji Hammera i na Twoją specjalną rpośbę.\n"
                        else:
                            reply += (
                                f"{index}. {plik[1]} z prywatnej kolekcji Hammera.\n"
                            )

                        index += 1
                        if len(reply) > 1800:
                            await ctx.send(reply)
                            reply = ""
            else:
                await ctx.send(
                    "Obawiam się że nie mogę nic znaleźć u siebie. Spróbuj komendy '$dej_co_ze_spotifaja' jeśli masz link"
                )
            await ctx.send(reply)
            self.logger.info("Plejlista zrobiona")

    @commands.hybrid_command(
        name="zagraj_muzyke_mego_ludu",
        description="Gra muzyke wyszukana na bazie tematow konwersacji na kanale NZ",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def zagraj_muzyke_mego_ludu(self, ctx):
        """
        Play completeley random playlist based on messaging history.

        :param ctx: ctx stands for "context" and is typically used in Discord.py commands to represent the
        context in which the command was invoked. This includes information such as the message, the
        channel, the author, and other relevant details. In this case, it is being passed as a parameter to
        the `get_image
        """
        stats = {}
        if ctx:
            self.logger.info("Zagraj muzyke mego ludu: wywolane")
            stat_iter = get_stats(self.bot, ctx, MUZYKA_MOJEGO_LUDU_HISTORIA)
            async for name, how_many in stat_iter:
                if len(name) > 3:
                    stats[name] = how_many

            sorted_stats = sorted(stats.items(), key=lambda x: x[1])
            self.logger.info("Zagraj muzyke mego ludu:zebrano statystyki")
            key_words = []
            for stat in sorted_stats:
                key_words.append(stat[0])
            self.logger.info(sorted_stats[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE])
            self.logger.info(key_words[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE])
            self.logger.info(sorted_stats[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])
            self.logger.info(key_words[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])

            final_key_words = key_words[:MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE]
            final_key_words.extend(key_words[-MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE:])
        reply = "Wygenerowana plejlista:\n"
        async with ctx.typing():
            self.logger.info(
                "Zagraj muzyke mego ludu:Zaczynam szukać timestamp %s", datetime.now()
            )
            search_time_glob = datetime.now()
            file = await music_functions.wyszukaj(
                ctx=ctx,
                how_many=MUZYKA_MOJEGO_LUDU_PLAJLISTA,
                slowa_kluczowe=final_key_words,
            )
            self.logger.info("Zagraj muzyke mego ludu:wygenerowano plejliste")
            self.logger.info(file)
            self.logger.info(
                "Zagraj muzyke mego ludu: Koniec szukania(timestamp %s zajęło %s",
                datetime.now(),
                datetime.now() - search_time_glob,
            )
            index = 1
            if file:
                for plik in file:
                    global MUZYKA  # pylint: disable=global-variable-not-assigned
                    MUZYKA["queue"].insert(0, plik[1])
                    MUZYKA["requester"].insert(0, ctx.author)
                    metadata = eyed3.load(plik[1])
                    if metadata and metadata.tag:
                        if metadata.tag.title:
                            reply += f"{index} {metadata.tag.title}"
                        else:
                            reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera."

                        if metadata.tag.artist:
                            reply += f" wykonawcy {metadata.tag.artist}"
                        if metadata.tag.album:
                            reply += f" z albumu {metadata.tag.album}"
                        if metadata.tag.title:
                            reply += " z prywatnej kolekcji Hammera i na Twoją specjalną rpośbę.\n"
                    else:
                        reply += f"{index}. {plik[1]} z prywatnej kolekcji Hammera.\n"

                    index += 1
                    if len(reply) > 1800:
                        await ctx.send(reply)
                        reply = ""
            else:
                await ctx.send(
                    "Obawiam się że nie mogę nic znaleźć u siebie. Spróbuj komendy '$dej_co_ze_spotifaja' jeśli masz link"
                )
            await ctx.send(reply)
            self.logger.info("Plejlista zrobiona")

    @commands.hybrid_command(
        name="parametry_muzyki_mego_ludu",
        description="Konfiguruje komende zagraj muzyke mojego ludu",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def parametry_muzyki_mego_ludu(
        self, ctx, ile_historii=1500, ile_slow_kluczowych=15, jak_dluga_plejlista=30
    ):
        """
        The function `parametry_muzyki_mego_ludu` sets global variables for the number of history entries,
        number of keywords, and length of playlist for a music application.

        :param ctx: The `ctx` parameter is typically used in Discord.py, a Python library for creating
        Discord bots. It represents the context of the command being executed, including information about
        the message, the server, and the user who invoked the command
        :param ile_historii: The parameter "ile_historii" represents the number of history items for the
        music playlist, defaults to 1500 (optional)
        :param ile_slow_kluczowych: The parameter "ile_slow_kluczowych" represents the number of keywords or
        key phrases related to music that you want to include in your analysis or search, defaults to 30
        (optional)
        :param jak_dluga_plejlista: The parameter "jak_dluga_plejlista" determines the length of the
        playlist. It specifies how many songs should be included in the playlist, defaults to 30 (optional)
        """

        if ctx:
            async with ctx.typing():
                # if ':' in ile_historii:
                #    _, _, ile_historii = ile_historii.partition(':')
                # if ':' in ile_slow_kluczowych:
                #    _, _, ile_slow_kluczowych = ile_slow_kluczowych.partition(':')
                # if ':' in jak_dluga_plejlista:
                #    _, _, jak_dluga_plejlista = jak_dluga_plejlista.partition(':')
                try:
                    global MUZYKA_MOJEGO_LUDU_HISTORIA  # pylint: disable=global-statement
                    global MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE  # pylint: disable=global-statement
                    global MUZYKA_MOJEGO_LUDU_PLAJLISTA  # pylint: disable=global-statement
                    self.logger.info(
                        "Długość historii wyszukiwania: %s\n Ilość słów kluczowych: %s\n Długość plejlisty do wygenerowanie: %s",
                        MUZYKA_MOJEGO_LUDU_HISTORIA,
                        MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE,
                        MUZYKA_MOJEGO_LUDU_PLAJLISTA,
                    )
                    ctx.send(
                        f"Dotychczasowe wartośći:\n Długość historii wyszukiwania: {MUZYKA_MOJEGO_LUDU_HISTORIA}\n Ilość słów kluczowych: {MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE}\n Długość plejlisty do wygenerowanie:{MUZYKA_MOJEGO_LUDU_PLAJLISTA}"
                    )
                    MUZYKA_MOJEGO_LUDU_HISTORIA = ile_historii
                    MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE = ile_slow_kluczowych
                    MUZYKA_MOJEGO_LUDU_PLAJLISTA = jak_dluga_plejlista
                    self.logger.info(
                        "Długość historii wyszukiwania: %s\n Ilość słów kluczowych: %s\n Długość plejlisty do wygenerowanie: %s",
                        MUZYKA_MOJEGO_LUDU_HISTORIA,
                        MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE,
                        MUZYKA_MOJEGO_LUDU_PLAJLISTA,
                    )
                    self.ctx.send(
                        f"Zmienione wartośći:\n Długość historii wyszukiwania: {MUZYKA_MOJEGO_LUDU_HISTORIA}\n Ilość słów kluczowych: {MUZYKA_MOJEGO_LUDU_SLOWA_KLUCZOWE}\n Długość plejlisty do wygenerowanie:{MUZYKA_MOJEGO_LUDU_PLAJLISTA}"
                    )
                except discord.ext.commands.errors.BadArgument as exce:
                    ctx.send("Spierdalaj")
                    self.logger.info(exce)

    @commands.hybrid_command(
        name="graj_muzyko",
        description="Włącza muzykę na kanale #nocna-zmiana.",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def graj_muzyko(self, ctx):
        """
        Async function named "graj_muzyko" starts music playback on channel "Nocna Zmiana".

        :param ctx: ctx stands for "context" and is a parameter commonly used in Discord.py commands. It
        represents the context in which the command was invoked, including information such as the message,
        the channel, the server, and the user who invoked the command. This parameter is required in all
        Discord.py commands
        """

        self.logger.info("Press play on tape")
        async with ctx.typing():
            global MUZYKA  # pylint: disable=global-variable-not-assigned
            MUZYKA["ctx"] = ctx
            await self.connect(ctx=ctx)
            await self.play(ctx=ctx)
            self.logger.info("Press play on tape completed")
            self.check_music.start()

    async def connect(self, ctx, arg=None):
        """
        Connect the bot to a voice channel if it is not already connected.

        :param ctx: ctx is short for context and refers to the context in which the command was invoked. It
        contains information about the message, the channel, the server, and the user who invoked the
        command
        :param arg: The `arg` parameter is an optional argument that can be passed to the `connect`
        function. It is not used in the code snippet provided, but it could potentially be used to specify a
        specific voice channel to connect to
        :return: If the voice client is already connected, the function will return without doing anything.
        If the function successfully connects to the voice channel, it will return a voice channel
        connection object. If it is not possible to connect to the voice channel, the function will log an
        error message and return nothing.
        """
        if ctx and arg:
            self.logger.info("Ctx and arg defined for connect")

        if self.bot.voice_clients:
            self.logger.info("Already connected with other client")
        else:
            vc = None
            if ctx.author.voice.channel:
                vc = await ctx.author.voice.channel.connect()
            else:
                voice_channel = self.bot.get_channel(1060349757349974066)
                vc = await voice_channel.connect()
            if not vc:
                self.logger.error("Not possible to connect to voice")
                return
            self.logger.info("Connected to voice")

    @commands.hybrid_command(
        name="batch_download",
        description="Zaciąga obiekty z pliku",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Legenda', 'Jarl', 'Thane' , 'Bartender')
    async def batch_download(self, ctx):
        content_type = ctx.message.attachments[0].content_type
        check = re.search("text\/plain; *charset=(.*)", content_type, re.IGNORECASE)
        await ctx.reply("Kurwa. Aleś mi roboty narobił... No nic. Ku radości. Skal!")
        async with ctx.typing():
            if check:
                global MUZYKA  # pylint: disable=global-variable-not-assigned
                file_bytes = await ctx.message.attachments[0].read()
                text = file_bytes.decode(encoding=check.group(1))
                self.logger.info(text)
                lines = text.split("\n")
                for link in lines:
                    link = link.strip()
                    self.logger.info(link)
                    pat = r"^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$"
                    self.logger.info("Verification")
                    if re.match(pat, link) and (
                        re.match(".*youtube.*", link) or re.match(".*youtu.be.*", link)
                    ):
                        self.logger.info("%s to link do jutuba", link)
                        dir_path, files = await music_functions.get_file(
                            ctx, "Youtube", link
                        )
                        if files:
                            for file_iter in files:
                                global MUZYKA  # pylint: disable=global-variable-not-assigned
                                MUZYKA["queue"].insert(0, file_iter)
                                music_functions.MUSIC_FILE_LIST.update_file_list(
                                    file_iter
                                )
                                MUZYKA["requester"].insert(0, ctx.author)
                                await ctx.send(f"Dodałem do listy {file_iter}")
                            self.logger.info("Jutub udany")

                    elif re.match(pat, link) and re.match(".*spotify.*", link):
                        self.logger.info("%s to link do spotify", link)
                        dir_path, files = await music_functions.get_file(
                            ctx, "Spotify", link
                        )
                        if platform == "win32":
                            separator = "\\"
                        else:
                            separator = "/"
                        for file in files:
                            file_path = (
                                dir_path
                                + separator
                                + file["artist"]
                                + " - "
                                + file["name"]
                                + ".mp3"
                            )

                            MUZYKA["queue"].insert(
                                0,
                                dir_path
                                + separator
                                + file["artist"]
                                + " - "
                                + file["name"]
                                + ".mp3",
                            )
                            MUZYKA["requester"].insert(0, ctx.author)
                            music_functions.MUSIC_FILE_LIST.update_file_list(file_path)
                            await ctx.send(
                                f"Dodałem do listy {dir_path}{file['artist']} -  + {file['name']}.mp3"
                            )
                            self.logger.info("Spotifaj udany")

                    elif re.match(pat, link):
                        self.logger.info("%s to link do czegos", link)
                        sciezka, files = await music_functions.get_file(
                            ctx, "Pornol", link
                        )
                        if files:
                            self.logger.info("Pornol udany")
                            await ctx.send(
                                f"Jest w tajnym archiwum pod adresem{sciezka})"
                            )

                    else:
                        self.logger.info("Spierdalaj")
                        self.logger.info(link)
                        await ctx.message.reply("Spierdalaj")
            else:
                self.logger.info(content_type)
                self.logger.info("Spierdalaj")
                await ctx.message.reply("Spierdalaj")

    async def disconnect(self, ctx):
        """
        Asynchronous Python function that disconnects the voice client if it is connected and
        logs a message if the context is defined.

        :param ctx: ctx is short for context and refers to the context in which a command is being executed.
        It contains information about the message, the user who sent the message, the channel the message
        was sent in, and more. In this case, the `disconnect` function is likely being called as a command
        in
        """
        if ctx:
            self.logger.info("Ctx defined for disconnect")
        if self.bot.voice_clients:
            voice_client = self.bot.voice_clients[0]
            if voice_client.is_connected():
                await voice_client.disconnect()

    async def play(self, ctx, zamawial=None, arg=None):
        """
        Play a music file, retrieve metadata about the file, and send a
        message to a Discord channel with information about the song being played.

        :param ctx: The "ctx" parameter is a context object that contains information about the current
        Discord command invocation, such as the message, the channel, and the user who invoked the command.
        It is passed to the function automatically by the Discord.py library
        :param zamawial: The parameter `zamawial` is a variable that stores the user who requested the song
        to be played. It is an optional parameter and can be None if no user requested the song
        :param arg: The `arg` parameter is an optional argument that can be passed to the `play` function.
        It is not used in the code provided, so its purpose is unclear without additional context
        """
        # TODO: Uzupełnianie metadanych. Jeśli ich nie ma sprawdzamy nazwę (w sposób inteligentny - czyli jeśli składa się z samych cyfr i/lub słowa track to sprawdzić album w sensie folder)
        # TODO: Jeśli w metadanych jest tylko "audiotrack" i "album" też po
        # folderze. Jeśli są niekompletne uzupełnić dalej.
        self.logger.info("Play procedure")
        if arg:
            self.logger.info("Arg defined for play")

        file_to_play = None
        voice_client = self.bot.voice_clients[0]
        if not self.bot.voice_clients:
            voice_client = self.bot.voice_clients[0]
            await self.connect(ctx)
        if MUZYKA["queue"]:
            file_to_play = MUZYKA["queue"].pop()
            zamawial = MUZYKA["requester"].pop()
            self.logger.info("Muzyka z listy zamówień")
        else:
            # trunk-ignore(bandit/B311)
            index = random.randint(
                0, len(music_functions.MUSIC_FILE_LIST.get_file_list()) - 1
            )
            file_to_play = music_functions.MUSIC_FILE_LIST.get_file_list()[index]
            self.logger.info("Muzyka losowo")

        self.logger.info(file_to_play)
        metadata = eyed3.load(file_to_play)
        query = None
        temp = file_to_play.split(SEPARATOR_FILE_PATH)[-1]
        kawalek = f"Zagram teraz kawalek {temp} z prywatnej kolekcji Hammera."
        if metadata:
            if metadata.tag:
                if metadata.tag.title:
                    query = f"Opowiedz mi o kawałku {metadata.tag.title}"
                    kawalek = f"Zagram teraz kawalek {metadata.tag.title}"
                    if metadata.tag.artist:
                        query += f" wykonawcy {metadata.tag.artist}"
                        kawalek += f" wykonawcy {metadata.tag.artist}"
                    if metadata.tag.album:
                        query += f" z albumu {metadata.tag.album}"
                        kawalek += f" z albumu {metadata.tag.album}"
                    kawalek += " z prywatnej kolekcji Hammera."
        if zamawial:
            kawalek += f"Na specjalne życzenie <@{zamawial.id}>."
        await ctx.send(kawalek)

        voice_client.play(
            discord.PCMVolumeTransformer(
                discord.FFmpegPCMAudio(source=file_to_play), volume=0.3
            )
        )  # NIE DOTYKAC POKRĘTŁA GŁOŚNOŚCI!!!!
        if query:
            self.logger.debug("Zapytanie do openai")
            self.logger.debug(query)
            vykidailo = False
            bartender = False
            for role in ctx.message.author.roles:
                if role.name == "Vykidailo":
                    vykidailo = True
                if role.name == "Bartender":
                    bartender = True
            if ctx.message.author.nick:
                username = ctx.message.author.nick
            else:
                username = ctx.message.author.name
            global MESSAGE_TABLE_MUZYKA  # pylint: disable=global-statement
            result, MESSAGE_TABLE_MUZYKA = await handle_response(
                query, vykidailo, bartender, MESSAGE_TABLE_MUZYKA, username, "MUSIC"
            )
            self.logger.debug("Obecna historia czatu: %s", MESSAGE_TABLE_MUZYKA)
            if len(result) < 1500:
                await ctx.send(result)
            else:
                while len(result) > 1500:
                    await ctx.send(result[:1500])
                    result = result[1500:]


async def setup(bot):
    logger = logging.getLogger("discord")
    await music_functions.MUSIC_FILE_LIST.refresh_file_list(bot)
    logger.info("Playlist generation")
    await bot.add_cog(MusicModule(bot, "discord"))
    logger.info("Loading music commands module done")
