from asyncio import run

from telethon import TelegramClient
from telethon.events import NewMessage
from telethon.utils import resolve_bot_file_id

from utils import (
  parse_command,
  get_link_to_user,
  Kind
)
from config import config
from db import init_db
from actions import (
  find_action, 
  get_random_gif,
  is_admin
)
from commands import COMMANDS

bot = TelegramClient(
  'openkriemy', 
  config.API_ID, 
  config.API_HASH
).start(bot_token=config.API_TOKEN)
 
@bot.on(NewMessage)
async def on_message(event):
  try:
    command = parse_command(event.text)
  except ValueError:
    return

  handler = COMMANDS.get(command.name, None)

  if handler:
    if handler.is_restricted\
   and not await is_admin(bot, event.sender):
      await event.reply('К сожалению, данная команда Вам недоступна.')
    else:
      await handler.handler(bot, event, command)

    return
     
  try:
    action = await find_action(command.name)
  except SyntaxError:
    return

  if not action:
    return

  reply_to = None
  target = None

  if action.kind != Kind.NO_TARGET:
    target = await event.get_reply_message()

    if not target:
      try:
        target = await bot.get_entity(command.args[0])
      except (ValueError, IndexError):
        await event.reply('Это действие нужно применить на кого-то!')

        return 
    else:
      reply_to = target
      target = target.sender

    if target is None:
      target = await bot.get_entity(event.peer_id.channel_id)

    if action.kind == Kind.CANNOT_APPLY_TO_SELF\
   and target.id == event.sender.id:
      await event.reply('Данное действие нельзя применять к самому себе...')

      return 
    
  try:
    await event.delete()
  except:
    pass
    
  if event.sender is None:
    initiator = await bot.get_entity(event.peer_id.channel_id)
    initiator = initiator.title
  else:
    initiator = get_link_to_user(event.sender)

  text = action.template.format(**{
    'initiator': initiator,
    'target': get_link_to_user(target) if target else '?'
  })
  
  gif = await get_random_gif(action)

  if gif:
    gif = resolve_bot_file_id(gif.file_id)

  await bot.send_message(
    event.peer_id,
    message=text,
    file=gif,
    reply_to=reply_to
  )
  
with bot:
  bot.loop.run_until_complete(init_db())
  bot.start()
  bot.run_until_disconnected()