from . import command, photo_fn, always, sticker_reply_fn, photo_fn, sticker_source_fn
from sh import convert as conv_unbaked, composite as comp_unbaked, ffmpeg as ffmpeg_unbaked
from schema import StickerPack
import telegram


# disable _tty_out to compact the AppArmor profile :)
convert = conv_unbaked.bake(_tty_out=False)
composite = comp_unbaked.bake(_tty_out=False)
ffmpeg = ffmpeg_unbaked.bake(_tty_out=False)

collect_uid_pack_map = {}

@command('list packs')
def list_packs(bea, bot, update):
    output = []
    packs = [pack for pack in StickerPack.select()]
    packs.sort(key=lambda pack: len(pack.title))
    for pack in packs:
        output.append(f"<a href='https://telegram.me/addstickers/{pack.shortname}'>{pack.title}</a>: {pack.shortname.split('_by_tfckbot')[0]}")
    bea.reply('\n'.join(output), parse_mode='HTML')

@command('newstickerset (\S+) (\S+) (.+)', pass_groups=True, additional_match_fn=photo_fn)
def create_set(bea, bot, update, photo, groups):
    """ Create a new sticker set. Arguments: emoji, short name, title.

    This needs to be a reply to a photo, which will become the first sticker in the pack. The given emoji will be associated with it."""
    emoji, shortname, title = groups
    shortname += "_by_tfckbot" # fuck de bot api maar whatever
    user_id = update.effective_user.id

    photo.get_file().download('newsticker.png')
    convert('newsticker.png', '-resize', '512x512', 'newstickerout.png')
    with open('newstickerout.png', 'rb') as f:
        res = True
        try:
            res = bot.create_new_sticker_set(user_id, shortname, title, png_sticker=f, emojis=emoji)
        except telegram.TelegramError:
            update.message.reply_text("Unable to create pack.. are the arguments in the right order?")
            res = False

        if res:
            StickerPack.create(uid=user_id, shortname=shortname, title=title)
            update.message.reply_text("Created new pack by that name!")


@command('collect (\S+)', pass_groups=True)
def collect_stickers(bea, bot, update, groups):
    """ Start collecting stickers for a pack. This causes Bea to interpret every sent image as a new sticker, and the emoji in its caption as the corresponding emoji. """
    name = groups[0]
    name += "_by_tfckbot"

    pack = StickerPack.get_or_none(StickerPack.shortname == name)
    if not pack:
        return update.message.reply_text("I don't know of a pack by that name..")

    id = update.effective_user.id

    if not bea.try_register_bypass(id, collection_helper):
        return update.message.reply_text("Registering bypass function failed - are you already bypassing something?")
    else:
        collect_uid_pack_map[id] = (name, 0)
        return update.message.reply_text("Collecting... (end with 'Bea: end collect')")

@command('delsticker', additional_match_fn=sticker_reply_fn)
def del_sticker(bea, bot, update, sticker):
    """ Delete a sticker from a pack. Send this in reply to a sticker. """
    pack = StickerPack.get_or_none(StickerPack.shortname == sticker.set_name)
    if not pack:
        return update.message.reply_text("I don't manage the pack that sticker is from.")

    try:
        if bot.delete_sticker_from_set(sticker.file_id):
            update.message.reply_text("Successfully deleted!")
    except telegram.TelegramError:
        update.message.reply_text("Unable to delete sticker.")

@command('addsticker (\S+) (\S+)', pass_groups=True, additional_match_fn=sticker_source_fn)
def add_sticker(bea, bot, update, src, groups):
    """ Add a sticker with the given emoji to pack. Arguments: emoji, pack shortname. """
    emoji, name = groups
    name += "_by_tfckbot"

    pack = StickerPack.get_or_none(StickerPack.shortname == name)
    if not pack:
        return update.message.reply_text("I don't know of a pack by that name..")

    if isinstance(src, telegram.PhotoSize) or isinstance(src, telegram.Document):
        src.get_file().download('newsticker.png')
        convert('newsticker.png', '-resize', '512x512', 'newstickerout.png')
        add_args = {'png_sticker': open('newstickerout.png', 'rb')}
    elif isinstance(src, telegram.Animation) or isinstance(src, telegram.Video):
        src.get_file().download('newvsticker')
        scale_arg = 'scale=512:-1' if src.width > src.height else 'scale=-1:512'

        ffmpeg('-y', '-i', 'newvsticker', '-c:v', 'libvpx-vp9', '-crf', '34', '-b:v', '0', '-an', '-r', '30', '-t', '3',
               '-vf', scale_arg, 'newvsticker.webm')
        add_args = {'webm_sticker': open('newvsticker.webm', 'rb')}
    else:
        raise ValueError('unknown sticker source')

    id = pack.uid
    try:
        if bot.add_sticker_to_set(id, name, emoji, **add_args):
            update.message.reply_text('Sticker added.')
    except telegram.TelegramError:
        update.message.reply_text("Something went wrong. Are your arguments in the right order?")

@command('(end collect)?', pass_groups=True, bypass_fn=always)
def collection_helper(bea, bot, update, groups):
    id = update.effective_user.id
    if groups and (groups[0] == 'end collect'):
        if not bea.unregister_bypass(id, collection_helper):
            return update.message.reply_text("Unable to unregister bypass, did you try to end collecting stickers when I wasn't doing that?")
        else:
            _, added_stickers = collect_uid_pack_map[id]
            del collect_uid_pack_map[id]
            return update.message.reply_text(f"Success. Added {added_stickers} stickers.")

    name, added_stickers = collect_uid_pack_map[id]

    if update.message.sticker:
        # it's already a sticker. steal it.
        sticker = update.message.sticker
        sticker.get_file().download('sticker.webp')
        convert('sticker.webp','newstickerout.png')
        emoji = sticker.emoji
    else:
        try:
            photo = photo_fn(update)
        except ValueError:
            return

        caption = update.effective_message.caption
        if not caption:
            return

        photo.get_file().download('newsticker.png')
        convert('newsticker.png', '-resize', '512x512', 'newstickerout.png')
        f = open('newstickerout.png', 'rb')

        emoji = caption

    try:
        if bot.add_sticker_to_set(id, name, emoji, f):
            collect_uid_pack_map[id] = (name, added_stickers + 1)
    except telegram.TelegramError:
        update.message.reply_text("Something went wrong.. are those emoji in the caption?")

@command('steal(?: (\S+)(?: (.+))?)?', additional_match_fn=sticker_reply_fn, pass_groups=True)
def steal_sticker(bea, bot, update, sticker, groups):
    """ Steal a sticker, adding it to Beapack. """
    emoji, pack_name = groups
    pack_name = pack_name or 'bpack'
    emoji = emoji or sticker.emoji
    pack = StickerPack.get_or_none(StickerPack.shortname == pack_name + '_by_tfckbot')
    if not pack:
        return update.message.reply_text("I don't know of a pack by that name...")
    sticker.get_file().download('sticker.webp')
    convert('sticker.webp','sticker.png')
    if bot.add_sticker_to_set(pack.uid, pack.shortname, emoji, open('sticker.png', 'rb')):
        update.message.reply_to_message.reply_sticker(sticker="CAACAgQAAxkBAAIO_V6NAnjnxSxVaoOgSRN2GyA_yec6AAJ3AgAC6DSzAqmfA-HmNynaGAQ", quote=True)

@command('unsticker', additional_match_fn=sticker_reply_fn)
def unsticker(bea, bot, update, sticker):
    sticker.get_file().download('sticker.webp')
    convert('sticker.webp','sticker.png')
    update.message.reply_to_message.reply_photo(open("sticker.png", 'rb'))

def init(bea, _config):
    return [unsticker, list_packs, del_sticker, collect_stickers, add_sticker, create_set, steal_sticker]
