from aiogram import Router, Bot, types, F
from aiogram.filters import Command, CommandObject

router_duplicate = Router()

MAX_SIZE_TEXT = 200
COPY_INFO = """<blockquote>/copy, /replace</blockquote> - copy the message by replying to the message
<blockquote>/copy + text, /replace + text</blockquote> - replace text string by replying to the bot message
if album - /copy 1-10

<blockquote>/forward, /fwd</blockquote> - forwarding the selected message

<blockquote>/short</blockquote> - shortens the selected long message (text size: {MAX_SIZE_TEXT}+)

<blockquote>/c_add</blockquote> - to add to the message
""".format(MAX_SIZE_TEXT=MAX_SIZE_TEXT)


async def _edit_message_text_or_caption(bot: Bot, message: types.Message, new_text: str, new_entities: list):
    """Edits either the text or caption of a message, depending on its content."""
    if message.text:
        await bot.edit_message_text(
            message_id=message.message_id,
            chat_id=message.chat.id,
            text=new_text,
            entities=new_entities,
            parse_mode=None
        )
    else:
        await bot.edit_message_caption(
            message_id=message.message_id,
            chat_id=message.chat.id,
            caption=new_text[:1024],
            caption_entities=new_entities,
            parse_mode=None
        )

async def _copy_or_forward_and_delete(bot: Bot, message: types.Message, forward=False):
    if forward:
        """Forwards a message and then deletes the original."""
        await bot.forward_message(
            chat_id=message.chat.id,
            from_chat_id=message.chat.id,
            message_id=message.message_id,
            message_thread_id=message.message_thread_id if message.is_topic_message else None
        )
    else:
        """Copies a message and then deletes the original."""
        await bot.copy_message(
            chat_id=message.chat.id,
            from_chat_id=message.chat.id,
            message_id=message.message_id,
            message_thread_id=message.message_thread_id if message.is_topic_message else None,
            caption=message.caption,
        )
    try:
        await bot.delete_message(message.chat.id, message.message_id)
    except Exception as ex:
        print("_copy_or_forward_and_delete(Error deleting message): ", ex)


async def edit_message_or_caption(bot: Bot, message: types.Message, command: CommandObject):
    """Edits the text or caption of a replied message, adjusting entity offsets."""
    reply = message.reply_to_message
    text = command.args
    entities = [
        types.MessageEntity(
            type=e.type,
            offset=e.offset - len(command.command) + 2,
            length=e.length,
            url=e.url,
            user=e.user,
            language=e.language,
            custom_emoji_id=e.custom_emoji_id,
        )
        for e in message.entities or []
    ]
    await _edit_message_text_or_caption(bot, reply, text, entities)


@router_duplicate.message(Command("copy", "replace"))
async def handle_copy_replace_command(message: types.Message, command: CommandObject, bot: Bot):
    reply = message.reply_to_message
    if not reply or reply.forum_topic_created:
        return await message.reply(COPY_INFO)

    try:
        await message.delete()
    except Exception as ex:
        print("Error deleting message:", ex)

    if command.args and reply.from_user.is_bot and command.args != (reply.text or reply.caption or ""):
        return await edit_message_or_caption(bot, message, command)

    if reply.media_group_id and command.args and command.args.isdigit() and 1 <= int(command.args) <= 10:
        ids = [reply.message_id + _ for _ in range(int(command.args))]
        message_album = await bot.copy_messages(
            chat_id=reply.chat.id,
            from_chat_id=reply.chat.id,
            message_thread_id=reply.message_thread_id if reply.is_topic_message else None,
            remove_caption=True,
            message_ids=ids
        )
        if reply.caption:
            await _edit_message_text_or_caption(bot, message_album[0], reply.caption[:1024], reply.entities)
        try:
            await bot.delete_messages(chat_id=reply.chat.id, message_ids=ids)
        except Exception as ex:
            print("Error deleting messages:", ex)
        return

    await _copy_or_forward_and_delete(bot, reply)


@router_duplicate.message(Command("forward", "fwd"))
async def handle_forward_command(message: types.Message, command: CommandObject, bot: Bot):
    reply = message.reply_to_message
    if not reply or reply.forum_topic_created:
        return await message.reply(COPY_INFO)

    try:
        await message.delete()
    except Exception as ex:
        print("handle_forward_command Error deleting message:", ex)

    if reply.media_group_id and command.args and command.args.isdigit() and 1 <= int(command.args) <= 10:
        ids = [reply.message_id + _ for _ in range(int(command.args))]
        await bot.forward_messages(
            chat_id=reply.chat.id,
            from_chat_id=reply.chat.id,
            message_thread_id=reply.message_thread_id if reply.is_topic_message else None,
            remove_caption=True,
            message_ids=ids
        )
        try:
            await bot.delete_messages(chat_id=reply.chat.id, message_ids=ids)
        except Exception as ex:
            print("Error deleting messages:", ex)
        return

    await _copy_or_forward_and_delete(bot, reply, forward=True)


@router_duplicate.message(Command("short"))
async def handle_short_command(message: types.Message, command: CommandObject, bot: Bot):
    reply = message.reply_to_message
    if not reply or reply.forum_topic_created:
        return await message.reply(COPY_INFO)

    user_link = f"<a href='tg://user?id={message.from_user.id}'>{message.from_user.full_name}</a>"
    reply_user_link = f"<a href='tg://user?id={reply.from_user.id}'>{message.from_user.full_name}</a>"

    reply_text = reply.text or reply.caption
    if reply_text and len(reply_text) > MAX_SIZE_TEXT:
        try:
            await message.delete()
        except Exception as ex:
            print("handle_short_command(Error deleting message):", ex)

        formatted_message = f"Message from {reply_user_link} shortened {user_link}\n<blockquote expandable>{reply_text}</blockquote>"
        if reply.text:
            await bot.send_message(
                chat_id=reply.chat.id,
                message_thread_id=reply.message_thread_id if reply.is_topic_message else None,
                text=formatted_message,
            )
        else:
            await bot.copy_message(
                chat_id=reply.chat.id,
                from_chat_id=reply.chat.id,
                message_id=reply.message_id,
                message_thread_id=reply.message_thread_id if reply.is_topic_message else None,
                caption=formatted_message,
            )
        try:
            await bot.delete_message(reply.chat.id, reply.message_id)
        except Exception as ex:
            print("handle_short_command(2 Error deleting message):", ex)
    else:
        await message.reply(COPY_INFO)


@router_duplicate.message(Command("c_add"))
async def handle_c_add_command(message: types.Message, command: CommandObject, bot: Bot):
    """
    Adds text from the command to the replied message, preserving formatting entities.

    :param message: The original message containing the command.
    :param command: The parsed command object.
    :param bot: The bot instance.
    """

    reply = message.reply_to_message
    if not reply or not command.args:
        return await message.reply("Reply to a message and provide text to add with /c_add command.")

    original_text = reply.text or reply.caption or ""
    text_to_add = message.text[len(command.command) + 1:]

    # Adjust entity offsets for the added text
    new_entities = reply.entities or []
    for entity in message.entities or []:
        if entity.offset > len(command.command):
            entity.offset += len(original_text) - len(command.command) + 1
            new_entities.append(entity)

    new_text = original_text + text_to_add

    try:
        await message.delete()
        await _edit_message_text_or_caption(bot, reply, new_text, new_entities)
    except Exception:
        pass  # Ignore errors if the message can't be edited

File "/root/myenv/edbotes/functions/duplicate_message/handlers_duplicate_message.py", line 105, in handle_copy_replace_command
    await _edit_message_text_or_caption(bot, message_album[0], reply.caption[:1024], reply.entities)
  File "/root/myenv/edbotes/functions/duplicate_message/handlers_duplicate_message.py", line 21, in _edit_message_text_or_caption
    if message.text:
       ^^^^^^^^^^^^
  File "/root/myenv/lib/python3.12/site-packages/pydantic/main.py", line 811, in __getattr__
    raise AttributeError(f'{type(self).__name__!r} object has no attribute {item!r}')
AttributeError: 'MessageId' object has no attribute 'text'