import asyncio
import string

import disnake
import youtube_transcript_api

from state import client, kill, players


async def transcript(
    message, languages=["en"], max_messages=6, min_messages=3, upper=True
):
    initial_id = message.guild.voice_client.source.id
    transcript_list = youtube_transcript_api.YouTubeTranscriptApi.list_transcripts(
        initial_id
    )
    try:
        transcript = transcript_list.find_manually_created_transcript(languages).fetch()
    except Exception:
        transcript = transcript_list.find_generated_transcript(languages).fetch()
        await message.channel.send("(autogenerated)")

    messages = []
    for line in transcript:
        if (
            players[message.guild.id].current.player.original.progress
            >= line["start"] + line["duration"]
        ):
            continue

        while (
            players[message.guild.id].current.player.original.progress < line["start"]
        ):
            await asyncio.sleep(0.2)

        messages.insert(
            0,
            await message.channel.send(line["text"].upper() if upper else line["text"]),
        )
        if len(messages) > max_messages:
            try:
                count = min(min_messages, len(messages))
                if count == 1:
                    await messages.pop().delete()
                else:
                    await message.channel.delete_messages(
                        [messages.pop() for _ in range(count)]
                    )
            except Exception:
                pass

        if (message.guild.voice_client.source.id != initial_id) or kill["transcript"]:
            break


def messages_per_second(limit=500):
    oldest = 2**64
    newest = 0
    guilds = set()
    members = set()
    cached_messages = list(client.cached_messages)[-limit:]

    for message in cached_messages:
        if message.guild:
            guilds.add(message.guild.id)
        members.add(message.author.id)

        t = message.created_at.timestamp()
        if t < oldest:
            oldest = t
        elif t > newest:
            newest = t

    average = round(len(cached_messages) / (newest - oldest), 1)
    if average == 1.0:
        average = 1
    print(
        f"I am receiving **{average} {'message' if average == 1 else 'messages'} per second** "
        f"from **{len(members)} {'member' if len(members) == 1 else 'members'}** across **{len(guilds)} {'guild' if len(guilds) == 1 else 'guilds'}**"
    )


async def auto_count(channel_id):
    if (channel := await client.fetch_channel(channel_id)) and isinstance(
        channel, disnake.TextChannel
    ):
        last_message = (await channel.history(limit=1).flatten())[0]
        try:
            result = str(
                int("".join(filter(lambda d: d in string.digits, last_message.content)))
                + 1
            )
        except Exception:
            result = "where number"
        await channel.send(result)