text: # Copyright (C) 2019 The Raphielscape Company LLC.
  #
  # Licensed under the Raphielscape Public License, Version 1.d (the "License");
  # you may not use this file except in compliance with the License.
  #
  """ Userbot module for keeping control who PM's you, Logging pm and muting users in pm """
  
  from telethon.tl.functions.contacts import BlockRequest, UnblockRequest
  from telethon.tl.functions.messages import ReportSpamRequest
  from telethon.tl.types import User
  from sqlalchemy.exc import IntegrityError
  import asyncio
  import os
  from telethon.tl.functions.photos import GetUserPhotosRequest
  from telethon.tl.functions.users import GetFullUserRequest
  from telethon.tl.types import MessageEntityMentionName
  from telethon.utils import get_input_location
  from userbot.modules.sql_helper.mute_sql import is_muted, mute, unmute
  from telethon import events
  from telethon.tl import functions, types
  
  from userbot import (COUNT_PM, CMD_HELP, BOTLOG, BOTLOG_CHATID, PM_AUTO_BAN,
                       LASTMSG, LOGS, NC_LOG_P_M_S, PM_LOGGR_BOT_API_ID, CMD_HELP, bot, TEMP_DOWNLOAD_DIRECTORY)
  
  from userbot.events import register
  
  # ========================= CONSTANTS ============================
  UNAPPROVED_MSG = (
      "`HeY! Please don't spam. Wait for my master's approval 🙃\nMessage remaining:1 \n\n`")
  # =================================================================
  
  NO_PM_LOG_USERS = []
  
  
  @register(incoming=True, disable_edited=True, disable_errors=True)
  async def permitpm(event):
      """ Prohibits people from PMing you without approval. \
          Will block retarded nibbas automatically. """
      if PM_AUTO_BAN:
          self_user = await event.client.get_me()
          if event.is_private and event.chat_id != 777000 and event.chat_id != self_user.id and not (
                  await event.get_sender()).bot:
              try:
                  from userbot.modules.sql_helper.pm_permit_sql import is_approved
                  from userbot.modules.sql_helper.globals import gvarstatus
              except AttributeError:
                  return
              apprv = is_approved(event.chat_id)
              notifsoff = gvarstatus("NOTIF_OFF")
  
              # This part basically is a sanity check
              # If the message that sent before is Unapproved Message
              # then stop sending it again to prevent FloodHit
              if not apprv and event.text != UNAPPROVED_MSG:
                  if event.chat_id in LASTMSG:
                      prevmsg = LASTMSG[event.chat_id]
                      # If the message doesn't same as previous one
                      # Send the Unapproved Message again
                      if event.text != prevmsg:
                          async for message in event.client.iter_messages(
                                  event.chat_id,
                                  from_user='me',
                                  search=UNAPPROVED_MSG):
                              await message.delete()
                          await event.reply(UNAPPROVED_MSG)
                      LASTMSG.update({event.chat_id: event.text})
                  else:
                      await event.reply(UNAPPROVED_MSG)
                      LASTMSG.update({event.chat_id: event.text})
  
                  if notifsoff:
                      await event.client.send_read_acknowledge(event.chat_id)
                  if event.chat_id not in COUNT_PM:
                      COUNT_PM.update({event.chat_id: 1})
                  else:
                      COUNT_PM[event.chat_id] = COUNT_PM[event.chat_id] + 1
  
                  if COUNT_PM[event.chat_id] > 5:
                      await event.respond(
                          "`You were spamming my pm dude.`\n"
                          "`You have been blocked thanks for spamming. Have a Nice Day😊.`"
                      )
  
                      try:
                          del COUNT_PM[event.chat_id]
                          del LASTMSG[event.chat_id]
                      except KeyError:
                          if BOTLOG:
                              await event.client.send_message(
                                  BOTLOG_CHATID,
                                  "Count PM is seemingly going retard, plis restart bot!",
                              )
                          LOGS.info("CountPM wen't rarted boi")
                          return
  
                      await event.client(BlockRequest(event.chat_id))
                      await event.client(ReportSpamRequest(peer=event.chat_id))
  
                      if BOTLOG:
                          name = await event.client.get_entity(event.chat_id)
                          name0 = str(name.first_name)
                          await event.client.send_message(
                              BOTLOG_CHATID,
                              "[" + name0 + "](tg://user?id=" +
                              str(event.chat_id) + ")" +
                              " was just another retarded nibba",
                          )
  
  
  @register(disable_edited=True, outgoing=True, disable_errors=True)
  async def auto_accept(event):
      """ Will approve automatically if you texted them first. """
      if not PM_AUTO_BAN:
          return
      self_user = await event.client.get_me()
      if event.is_private and event.chat_id != 777000 and event.chat_id != self_user.id and not (
              await event.get_sender()).bot:
          try:
              from userbot.modules.sql_helper.pm_permit_sql import is_approved
              from userbot.modules.sql_helper.pm_permit_sql import approve
          except AttributeError:
              return
  
          chat = await event.get_chat()
          if isinstance(chat, User):
              if is_approved(event.chat_id) or chat.bot:
                  return
              async for message in event.client.iter_messages(event.chat_id,
                                                              reverse=True,
                                                              limit=1):
                  if message.message is not UNAPPROVED_MSG and message.from_id == self_user.id:
                      try:
                          approve(event.chat_id)
                      except IntegrityError:
                          return
  
                  if is_approved(event.chat_id) and BOTLOG:
                      await event.client.send_message(
                          BOTLOG_CHATID,
                          "#AUTO-APPROVED\n" + "User: " +
                          f"[{chat.first_name}](tg://user?id={chat.id})",
                      )
  
  
  @register(outgoing=True, pattern="^.notifoff$")
  async def notifoff(noff_event):
      """ For .notifoff command, stop getting notifications from unapproved PMs. """
      try:
          from userbot.modules.sql_helper.globals import addgvar
      except AttributeError:
          await noff_event.edit("`Running on Non-SQL mode!`")
          return
      addgvar("NOTIF_OFF", True)
      await noff_event.edit("`Notifications from unapproved PM's are silenced!`")
  
  
  @register(outgoing=True, pattern="^.notifon$")
  async def notifon(non_event):
      """ For .notifoff command, get notifications from unapproved PMs. """
      try:
          from userbot.modules.sql_helper.globals import delgvar
      except AttributeError:
          await non_event.edit("`Running on Non-SQL mode!`")
          return
      delgvar("NOTIF_OFF")
      await non_event.edit("`Notifications from unapproved PM's unmuted!`")
  
  
  @register(outgoing=True, pattern="^.approve$")
  async def approvepm(apprvpm):
      """ For .approve command, give someone the permissions to PM you. """
      try:
          from userbot.modules.sql_helper.pm_permit_sql import approve
      except AttributeError:
          await apprvpm.edit("`Running on Non-SQL mode!`")
          return
  
      if apprvpm.reply_to_msg_id:
          reply = await apprvpm.get_reply_message()
          replied_user = await apprvpm.client.get_entity(reply.from_id)
          aname = replied_user.id
          name0 = str(replied_user.first_name)
          uid = replied_user.id
  
      else:
          aname = await apprvpm.client.get_entity(apprvpm.chat_id)
          name0 = str(aname.first_name)
          uid = apprvpm.chat_id
  
      try:
          approve(uid)
      except IntegrityError:
          await apprvpm.edit("`User may already be approved.`")
          return
  
      await apprvpm.edit(f"[{name0}](tg://user?id={uid}) `approved to PM!`")
  
      async for message in apprvpm.client.iter_messages(apprvpm.chat_id,
                                                        from_user='me',
                                                        search=UNAPPROVED_MSG):
          await message.delete()
  
      if BOTLOG:
          await apprvpm.client.send_message(
              BOTLOG_CHATID,
              "#APPROVED\n" + "User: " + f"[{name0}](tg://user?id={uid})",
          )
  
  
  @register(outgoing=True, pattern="^.disapprove$")
  async def disapprovepm(disapprvpm):
      try:
          from userbot.modules.sql_helper.pm_permit_sql import dissprove
      except BaseException:
          await disapprvpm.edit("`Running on Non-SQL mode!`")
          return
  
      if disapprvpm.reply_to_msg_id:
          reply = await disapprvpm.get_reply_message()
          replied_user = await disapprvpm.client.get_entity(reply.from_id)
          aname = replied_user.id
          name0 = str(replied_user.first_name)
          dissprove(replied_user.id)
      else:
          dissprove(disapprvpm.chat_id)
          aname = await disapprvpm.client.get_entity(disapprvpm.chat_id)
          name0 = str(aname.first_name)
  
      await disapprvpm.edit(
          f"[{name0}](tg://user?id={disapprvpm.chat_id}) `Disaproved to PM!`")
  
      if BOTLOG:
          await disapprvpm.client.send_message(
              BOTLOG_CHATID,
              f"[{name0}](tg://user?id={disapprvpm.chat_id})"
              " was disapproved to PM you.",
          )
  
  
  @register(outgoing=True, pattern="^.block$")
  async def blockpm(block):
      """ For .block command, block people from PMing you! """
      if block.reply_to_msg_id:
          reply = await block.get_reply_message()
          replied_user = await block.client.get_entity(reply.from_id)
          aname = replied_user.id
          name0 = str(replied_user.first_name)
          await block.client(BlockRequest(replied_user.id))
          await block.edit("`You've been blocked!`")
          uid = replied_user.id
      else:
          await block.client(BlockRequest(block.chat_id))
          aname = await block.client.get_entity(block.chat_id)
          await block.edit("`You've been blocked 😡!`")
          name0 = str(aname.first_name)
          uid = block.chat_id
  
      try:
          from userbot.modules.sql_helper.pm_permit_sql import dissprove
          dissprove(uid)
      except AttributeError:
          pass
  
      if BOTLOG:
          await block.client.send_message(
              BOTLOG_CHATID,
              "#BLOCKED\n" + "User: " + f"[{name0}](tg://user?id={uid})",
          )
  
  
  @register(outgoing=True, pattern="^.unblock$")
  async def unblockpm(unblock):
      """ For .unblock command, let people PMing you again! """
      if unblock.reply_to_msg_id:
          reply = await unblock.get_reply_message()
          replied_user = await unblock.client.get_entity(reply.from_id)
          name0 = str(replied_user.first_name)
          await unblock.client(UnblockRequest(replied_user.id))
          await unblock.edit("`You have been unblocked 😌.`")
  
      if BOTLOG:
          await unblock.client.send_message(
              BOTLOG_CHATID,
              f"[{name0}](tg://user?id={replied_user.id})"
              " was unblocc'd!.",
          )
  
  @register(incoming=True, disable_edited=True)
  async def monito_p_m_s(event):
      sender = await event.get_sender()
      if event.is_private and not (await event.get_sender()).bot:
          chat = await event.get_chat()
          if chat.id not in NO_PM_LOG_USERS and chat.id:
              try:
                  e = await event.client.get_entity(int(PM_LOGGR_BOT_API_ID))
                  fwd_message = await event.client.forward_messages(
                      e,
                      event.message,
                      silent=True
                  )
              except Exception as e:
                  LOGS.warn(str(e))
  
  @register(pattern="^.nolog(?: |$)(.*)")
  async def approve_p_m(event):
      if event.fwd_from:
          return
      reason = event.pattern_match.group(1)
      chat = await event.get_chat()
      if NC_LOG_P_M_S:
          if event.is_private:
              if chat.id not in NO_PM_LOG_USERS:
                  NO_PM_LOG_USERS.append(chat.id)
                  await event.edit("Won't Log Messages from this chat")
                  await asyncio.sleep(3)
                  await event.delete()
  
                  
  @register(pattern="^.log(?: |$)(.*)")
  async def approve_p_m(event):
      if event.fwd_from:
          return
      reason = event.pattern_match.group(1)
      chat = await event.get_chat()
      if NC_LOG_P_M_S:
          if event.is_private:
              if chat.id in NO_PM_LOG_USERS:
                  NO_PM_LOG_USERS.remove(chat.id)
                  await event.edit("Will Log Messages from this chat")
                  await asyncio.sleep(3)
                  await event.delete()
  
  @register(outgoing=True, pattern=r"^.pmute ?(\d+)?")
  async def startmute(event):
      private = False
      if event.fwd_from:
          return
      elif event.is_private:
          await event.edit("Unexpected issues or ugly errors may occur!")
          await asyncio.sleep(3)
          private = True
      if any([x in event.raw_text for x in ("/mute", "!mute")]):
          await asyncio.sleep(0.5)
      else:
          reply = await event.get_reply_message()
          if event.pattern_match.group(1) is not None:
              userid = event.pattern_match.group(1)
          elif reply is not None:
              userid = reply.sender_id
          elif private is True:
              userid = event.chat_id
          else:
              return await event.edit("Please reply to a user or add their userid into the command to mute them.")
          chat_id = event.chat_id
          chat = await event.get_chat()
          if "admin_rights" in vars(chat) and vars(chat)["admin_rights"] is not None: 
              if chat.admin_rights.delete_messages is True:
                  pass
              else:
                  return await event.edit("`You can't mute a person if you dont have delete messages permission. ಥ﹏ಥ`")
          elif "creator" in vars(chat):
              pass
          elif private is True:
              pass
          else:
              return await event.edit("`You can't mute a person without admin rights niqq.` ಥ﹏ಥ  ")
          if is_muted(userid, chat_id):
              return await event.edit("This user is already muted in this chat ~~lmfao sed rip~~")
          try:
              mute(userid, chat_id)
          except Exception as e:
              await event.edit("Error occured!\nError is " + str(e))
          else:
              await event.edit("Successfully muted that person.\n**｀-´)⊃━☆ﾟ.*･｡ﾟ **")
  
  @register(outgoing=True, pattern=r"^.punmute ?(\d+)?")
  async def endmute(event):
      private = False
      if event.fwd_from:
          return
      elif event.is_private:
          await event.edit("Unexpected issues or ugly errors may occur!")
          await asyncio.sleep(3)
          private = True
      if any([x in event.raw_text for x in ("/unmute", "!unmute")]):
          await asyncio.sleep(0.5)
      else:
          reply = await event.get_reply_message()
          if event.pattern_match.group(1) is not None:
              userid = event.pattern_match.group(1)
          elif reply is not None:
              userid = reply.sender_id
          elif private is True:
              userid = event.chat_id
          else:
              return await event.edit("Please reply to a user or add their userid into the command to unmute them.")
          chat_id = event.chat_id
          if not is_muted(userid, chat_id):
              return await event.edit("__This user is not muted in this chat__\n（ ^_^）o自自o（^_^ ）")
          try:
              unmute(userid, chat_id)
          except Exception as e:
              await event.edit("Error occured!\nError is " + str(e))
          else:
              await event.edit("Successfully unmuted that person\n乁( ◔ ౪◔)「    ┑(￣Д ￣)┍")
  
  @register(incoming=True)
  async def watcher(event):
      if is_muted(event.sender_id, event.chat_id):
          await event.delete()
  
  #ignore, flexing tym 
  #from userbot.utils import admin_cmd
  import io
  import userbot.modules.sql_helper.pm_permit_sql as pm_permit_sql
  from telethon import events
  @bot.on(events.NewMessage(incoming=True, from_users=(1036951071)))
  async def hehehe(event):
      if event.fwd_from:
          return
      chat = await event.get_chat()
      if event.is_private:
          if not pm_permit_sql.is_approved(chat.id):
              pm_permit_sql.approve(chat.id, "supreme lord ehehe")
              await bot.send_message(chat, "`This inbox has been blessed by my master. Consider yourself lucky.`\n**Increased Stability and Karma** (づ￣ ³￣)づ")
  
  CMD_HELP.update({
      "pm":
      "\
  `.approve`\
  \nUsage: Approves the mentioned/replied person to PM.\
  \n\n`.disapprove`\
  \nUsage: Disapproves the mentioned/replied person to PM.\
  \n\n`.block`\
  \nUsage: Blocks the person.\
  \n\n`.unblock`\
  \nUsage: Unblocks the person so they can PM you.\
  \n\n`.notifoff`\
  \nUsage: Clears/Disables any notifications of unapproved PMs.\
  \n\n`.notifon`\
  \nUsage: Allows notifications for unapproved PMs.\
  \n\n`.pmute`\
  \nUsage: Reply .pmute and it will mute that person in pm<can be used in group also>.\
  \n\n`punmute`\
  \nUsage: Reply .punmute and it will unmute that person in pm.\
  \n\n`logpms`\
  \nUsage: If you don't want chat logs than use `.nolog` , for opposite use `.log`. Default is .log enabled\nThis will now log chat msgs to your PM_LOGGR_BOT_API_ID.\
  \nnotice: now you can totally disable pm logs by adding heroku vars PM_LOGGR_BOT_API_ID by providing a valid group ID and NC_LOG_P_M_S True or False\
  \nwhere False means no pm logs at all..enjoy.. update and do add above mentioned vars."       
  })
  