import time
import math

class Progress:
    def __init__(self):
        pass

    def humanbytes(self, size):
        if not size:
            return "0B"
        power = 2**10
        n = 0
        Dic_powerN = {0: ' ', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'}
        while size > power:
            size /= power
            n += 1
        return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'

    def time_formatter(self, milliseconds: int) -> str:
        seconds, milliseconds = divmod(int(milliseconds), 1000)
        minutes, seconds = divmod(seconds, 60)
        hours, minutes = divmod(minutes, 60)
        days, hours = divmod(hours, 24)
        tmp = ((str(days) + "d, ") if days else "") + \
            ((str(hours) + "h, ") if hours else "") + \
            ((str(minutes) + "m, ") if minutes else "") + \
            ((str(seconds) + "s, ") if seconds else "") + \
            ((str(milliseconds) + "ms") if milliseconds else "")
        return tmp[:-2]

    async def progress_for_pyrogram(self, current, total, ud_type, message, start, last_update_time_store=None):
        now = time.time()
        diff = now - start
        
        # Only update if 5 seconds have passed since last update OR it is complete
        if last_update_time_store and (now - last_update_time_store[0]) < 5 and current != total:
            return

        if last_update_time_store:
            last_update_time_store[0] = now
            
        percentage = current * 100 / total
        speed = current / diff if diff > 0 else 0
        elapsed_time = round(diff) * 1000
        time_to_completion = round((total - current) / speed) * 1000 if speed > 0 else 0
        estimated_total_time = elapsed_time + time_to_completion
        
        elapsed_time_str = self.time_formatter(elapsed_time)
        estimated_time_str = self.time_formatter(estimated_total_time)
        
        progress = "[{0}{1}] \n**Progress**: {2}%\n".format(
            ''.join(["●" for i in range(math.floor(percentage / 5))]),
            ''.join(["○" for i in range(20 - math.floor(percentage / 5))]),
            round(percentage, 2))
        
        tmp = progress + "**{0}**: {1} of {2}\n**Speed**: {3}/s\n**ETA**: {4}".format(
            ud_type,
            self.humanbytes(current),
            self.humanbytes(total),
            self.humanbytes(speed),
            estimated_time_str if estimated_time_str else "0s"
        )
        try:
            await message.edit(
                text="{}\n{}".format(ud_type, tmp)
            )
        except Exception:
            pass

progress_helper = Progress()