import asyncio
import json
import logging
from datetime import datetime
from typing import Optional

import discord
from discord.ext import commands

from constants import ACCIDENT_LOG, DATA, ENCODING

historia_fabryczki = DATA["fabryczka"]


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

    @commands.hybrid_command(
        name="przytul", description="Przytul kogoś - daj mention po komendzie :)"
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def przytul(self, ctx, arg: Optional[discord.Member] = None):
        """
        Generate a text about hugging mentioned user.

        :param ctx: ctx stands for "context" and is a required parameter 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
        :param arg: arg is a parameter of the function "przytul" that expects a Discord member object. The
        parameter is optional, meaning that if no member object is provided, it will default to None
        :type arg: Optional[discord.Member]
        """
        async with ctx.typing():
            nieprzytulac = False
            for mention in ctx.message.mentions:
                for role in mention.roles:
                    if role.name == "NIEPRZYTULAĆ!":
                        nieprzytulac = True

            if arg and nieprzytulac:
                await ctx.send(
                    f"Żebym ja Ciebie nie przytulił {ctx.message.author.mention}"
                )
            elif arg:
                await ctx.send(
                    # trunk-ignore(codespell/misspelled)
                    f"Już dobrze.... Już dobrze... Ojej.. Biedactwo... :( *W ułamku sekundy {arg.mention} znajduje sie w duszącym uścisku. Żebra trzeszczą - kilka pęka. Pacnięcia po plecach grożą odbiciem nerek, a głaskanie po głowie powoduje wstrząs mózgu*"
                )
            else:
                await ctx.send(
                    "Kogo mam przytulić? *Wyłamuje kostki i przeciąga się - jego 200 kilowa sylwetka złożona z samych mięśni świadczy o tym że jest gotowy*"
                )

    @commands.hybrid_command(name="fabryczka", description="Historia fabryczki")
    @commands.has_any_role('Legenda', 'Jarl', 'Thane' , 'Bartender')
    async def fabryczka(self, ctx):
        """
        Send a general description of "fabryczkagate" to channel.

        :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. The context object provides a way to
        interact with the Discord
        """
        await ctx.send(historia_fabryczki)

    @commands.hybrid_command(
        name="set_logging_level",
        description="Nie intererer bo kici kici",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Legenda', 'Jarl', 'Bartender')
    async def set_logging_level(self,ctx):
        if "DEBUG" in ctx.message.content:
            logger = logging.getLogger("discord")
            logger.setLevel(logging.DEBUG)
        elif "INFO" in ctx.message.content:
            logger = logging.getLogger("discord")
            logger.setLevel(logging.INFO)
        else:
            await ctx.send("Weź się kurwa zdecyduj co ?")

    @commands.hybrid_command(
        name="reset_the_clock",
        description="Resetowanie zegara - dostępne wyłącznie dla Hammera",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Legenda', 'Jarl', 'Thane' , 'Bartender')
    async def reset_the_clock(self, ctx):
        """
        Reset the clock on "accidents" in Hammer Fortress adding a new one.

        :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
        """
        hammer = False
        for role in ctx.message.author.roles:
            if role.name == "Bartender":
                hammer = True
        if hammer:
            with open(ACCIDENT_LOG, "r+", encoding=ENCODING) as new_file_accidents:
                # First we load existing data into a dict.
                file_data = json.load(new_file_accidents)
                czas = datetime.strptime(file_data[-1][1], "%Y-%m-%d %H:%M:%S.%f")
                opis = ctx.message.content[16:]
                accident = accident = [opis, f"{datetime.now()}"]
                file_data.append(accident)
                new_file_accidents.seek(0)
                # convert back to json.
                json.dump(file_data, new_file_accidents, indent=4)
                await ctx.send(
                    f"Komenda mierząca incydenty w Eldritch AbsinthHammerTimeSpaceContinuum.\n RESET THE CLOCK. Od ostatniego incydentu w chacie Hammera minęło {czas}. No ale teraz się odpierdoliło: {opis}"
                )
        else:
            await ctx.send(
                f"Komenda mierząca incydenty w Eldritch AbsinthHammerTimeSpaceContinuum.\n Gdzie z łapami do zegara? {self.bot.get_user(346956223645614080).mention} coś albo się komuś stało albo zaraz się stanie jak będzie zegar tykał...."
            )

    @commands.hybrid_command(
        name="chata_hammera",
        description="Czas od ostatniego incydentu w AbsinthHammerTimeSpaceContinuum",
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def chata_hammera(self, ctx):
        """
        Send measured time from last incident in Hammer Fortress to the chat.

        :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
        """
        with open(ACCIDENT_LOG, "r+", encoding=ENCODING) as new_file:
            # First we load existing data into a dict.
            file_data = json.load(new_file)
            opis = file_data[-1][0]
            czas = datetime.strptime(file_data[-1][1], "%Y-%m-%d %H:%M:%S.%f")
            await ctx.send(
                f"Komenda mierząca incydenty w Eldritch AbsinthHammerTimeSpaceContinuum.\n Od ostatniego incydentu w chacie Hammera minęło {datetime.now() - czas}. Incydent to: {opis}"
            )

    @commands.hybrid_command(
        name="historia_incydentow_u_hammera",
        description="Wyswietla liste incydentów które miały miejsce w AbsinthHammerTimeSpaceContinuum.",
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def historia_incydentow_u_hammera(self, ctx):
        """
        Send a list of incidents in Hammer Fortress to the chat.

        :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
        """
        with open(ACCIDENT_LOG, "r+", encoding=ENCODING) as new_file_accidents:
            # First we load existing data into a dict.
            file_data = json.load(new_file_accidents)
            return_data = "Komenda mierząca incydenty w Eldritch AbsinthHammerTimeSpaceContinuum.\n Historia zarejestrownych incydentów u Hammera:\n"
            index = 1
            for iter_data in file_data:
                opis = iter_data[0]
                czas = datetime.strptime(iter_data[1], "%Y-%m-%d %H:%M:%S.%f")
                add_data = f"{index}. Opis: {opis} Data: {czas}"
                return_data = return_data + add_data + "\n"
                index += 1
            await ctx.send(return_data)

    @commands.hybrid_command(
        name="radio_hardkor",
        description="Włącza radio Conjurer na kanale #nocna-zmiana.",
        guild=discord.Object(id=664789470779932693),
    )
    @commands.has_any_role('Nocna Zmiana', 'Jarl', 'Thane' , 'Bartender')
    async def radio_hardkor(self, ctx):
        """
        Plays the radio hardkor stream in the voice channel.

        Args:
            ctx: The context object representing the invocation context.

        Returns:
            None
        """
        self.logger.info("Press play on radio hardkor")
        async with ctx.typing():
            global MUZYKA  # pylint: disable=global-variable-not-assigned
            MUZYKA["ctx"] = ctx
            if not self.bot.voice_clients:
                await self.connect(ctx=ctx)
                voice_client = self.bot.voice_clients[0]
                voice_client.play(
                    discord.PCMVolumeTransformer(
                        discord.FFmpegPCMAudio("http://95.175.16.246:666/mp3-stream"),
                        volume=0.3,
                    )
                )
                self.logger.info("Press play on radio completed")
            else:
                self.logger.error("Already playing")
            await asyncio.sleep(12)
            self.check_music.start()


async def setup(bot):
    logger = logging.getLogger("discord")
    await bot.add_cog(OtherModule(bot, "discord"))
    logger.info("Loading kitchen sink module done")
