from typing import Union, List

import telethon as tg
from .. import command, module, util
from re import compile, MULTILINE, IGNORECASE
from json import dumps
from telethon.tl.functions.messages import GetCommonChatsRequest

try:
    from BeautifulSoup import BeautifulSoup, element
except ImportError:
    from bs4 import BeautifulSoup, element

class TopListModule(module.Module):
    name = "Top Lists"
    # no_mention_pattern = compile(r'<template type="([\w_]+)" value_type="([\w_]+)">([\w\s_]+)</template>')
    # user_pattern = compile(r'<user id="(\d+)" first_name="\w+" last_name="\w+" user_name="\w+"/>')
    last_edited = 0

    async def parse_message(self, msg: tg.custom.Message):
        txt = msg.raw_text
        html = BeautifulSoup(txt, features="html.parser")
        user: element.Tag
        changes = 0
        for user in html.find_all("user"):
            changes += 1
            user.replace_with(util.bluscream.ParseUserStr(
                id=int(user.attrs["id"]) if user.has_attr("id") else None,
                first_name=user.attrs["first_name"] if user.has_attr("first_name") else None,
                last_name=user.attrs["last_name"] if user.has_attr("last_name") else None,
                user_name=user.attrs["user_name"] if user.has_attr("user_name") else None))
        if changes > 0 and self.last_edited != msg.id:
            self.last_edited = msg.id
            await msg.edit(html.text)
        """
        matches = self.no_mention_pattern.finditer(msg.text, MULTILINE | IGNORECASE)
        new_txt: str = msg.text
        for match in matches:
            repl = ""
            if match.group(1) == "no_mention":
                if match.group(2) == "userid":
                    repl = match.group(3)
            new_txt = new_txt.replace(match.group(0))
        """

    async def on_message(self, msg: tg.custom.Message):
        if msg.from_id != self.bot.uid: return
        print("on_msg")
        await self.parse_message(msg)

    async def on_message_edit(self, event: tg.events.MessageEdited.Event):
        if event.message.from_id != self.bot.uid: return
        print("on_msg_edit")
        await self.parse_message(event.message)

    @command.alias("top")
    async def cmd_toplist(self, msg: tg.custom.Message, count: int = 5):
        count = int(count) if count else 5
        chat: Union[tg.types.Chat, tg.types.Channel] = await msg.get_chat()
        members: List[tg.types.User] = list()
        member: tg.types.User
        async for member in  self.bot.client.iter_participants(chat):
            if member.is_self: continue
            chats = await self.bot.client(GetCommonChatsRequest(member, 0, 100))
            member.common_chats = len(chats.chats)
            if member.common_chats < 1: continue
            members.append(member)
        members.sort(key=lambda member: member.common_chats, reverse=True)
        if len(members) > count: members = members[:count]
        txt = f"**Top {len(members)} of {chat.title}:**\n"
        for member in members:
            txt += f"\n - `{member.common_chats}`: {util.bluscream.UserStr(member)}" + u'\u202C'
        return txt # "\n- ".join([f"`{member.common_chats}`: {util.bluscream.UserStr(member)}" for member in members])
        await msg.delete()
        await msg.respond(txt)
from typing import Union, List

import telethon as tg
from .. import command, module, util
from re import compile, MULTILINE, IGNORECASE
from json import dumps
from telethon.tl.functions.messages import GetCommonChatsRequest

try:
    from BeautifulSoup import BeautifulSoup, element
except ImportError:
    from bs4 import BeautifulSoup, element

class TopListModule(module.Module):
    name = "Top Lists"
    # no_mention_pattern = compile(r'<template type="([\w_]+)" value_type="([\w_]+)">([\w\s_]+)</template>')
    # user_pattern = compile(r'<user id="(\d+)" first_name="\w+" last_name="\w+" user_name="\w+"/>')
    last_edited = 0

    async def parse_message(self, msg: tg.custom.Message):
        txt = msg.raw_text
        html = BeautifulSoup(txt, features="html.parser")
        user: element.Tag
        changes = 0
        for user in html.find_all("user"):
            changes += 1
            user.replace_with(util.bluscream.ParseUserStr(
                id=int(user.attrs["id"]) if user.has_attr("id") else None,
                first_name=user.attrs["first_name"] if user.has_attr("first_name") else None,
                last_name=user.attrs["last_name"] if user.has_attr("last_name") else None,
                user_name=user.attrs["user_name"] if user.has_attr("user_name") else None))
        if changes > 0 and self.last_edited != msg.id:
            self.last_edited = msg.id
            await msg.edit(html.text)
        """
        matches = self.no_mention_pattern.finditer(msg.text, MULTILINE | IGNORECASE)
        new_txt: str = msg.text
        for match in matches:
            repl = ""
            if match.group(1) == "no_mention":
                if match.group(2) == "userid":
                    repl = match.group(3)
            new_txt = new_txt.replace(match.group(0))
        """

    async def on_message(self, msg: tg.custom.Message):
        if msg.from_id != self.bot.uid: return
        print("on_msg")
        await self.parse_message(msg)

    async def on_message_edit(self, event: tg.events.MessageEdited.Event):
        if event.message.from_id != self.bot.uid: return
        print("on_msg_edit")
        await self.parse_message(event.message)

    @command.alias("top")
    async def cmd_toplist(self, msg: tg.custom.Message, count: int = 5):
        count = int(count) if count else 5
        chat: Union[tg.types.Chat, tg.types.Channel] = await msg.get_chat()
        members: List[tg.types.User] = list()
        member: tg.types.User
        async for member in  self.bot.client.iter_participants(chat):
            if member.is_self: continue
            chats = await self.bot.client(GetCommonChatsRequest(member, 0, 100))
            member.common_chats = len(chats.chats)
            if member.common_chats < 1: continue
            members.append(member)
        members.sort(key=lambda member: member.common_chats, reverse=True)
        if len(members) > count: members = members[:count]
        txt = f"**Top {len(members)} of {chat.title}:**\n"
        for member in members:
            txt += f"\n - `{member.common_chats}`: {util.bluscream.UserStr(member)}" + u'\u202C'
        return txt # "\n- ".join([f"`{member.common_chats}`: {util.bluscream.UserStr(member)}" for member in members])
        await msg.delete()
        await msg.respond(txt)
# no_mention_pattern = compile(r'<template type="([\w_]+)" value_type="([\w_]+)">([\w\s_]+)</template>') # user_pattern = compile(r'<user id="(\d+)" first_name="\w+" last_name="\w+" user_name="\w+"/>') matches = self.no_mention_pattern.finditer(msg.text, MULTILINE | IGNORECASE)         new_txt: str = msg.text         for match in matches:             repl = ""             if match.group(1) == "no_mention":                 if match.group(2) == "userid":                     repl = match.group(3)             new_txt = new_txt.replace(match.group(0)) # "\n- ".join([f"`{member.common_chats}`: {util.bluscream.UserStr(member)}" for member in members])