"""
This plugin provides a command to fetch definitions from Urban Dictionary.
"""
import logging
import requests
import simplematrixbotlib as botlib
import html
URBAN_API_URL = "https://api.urbandictionary.com/v0/define"
RANDOM_API_URL = "https://api.urbandictionary.com/v0/random"
def format_definition(term, definition, example, author, thumbs_up, thumbs_down, permalink, index=None, total=None):
    """
    Format an Urban Dictionary definition for display.
    Args:
        term (str): The term being defined.
        definition (str): The definition text.
        example (str): Example usage.
        author (str): Author of the definition.
        thumbs_up (int): Number of upvotes.
        thumbs_down (int): Number of downvotes.
        permalink (str): URL to the definition.
        index (int, optional): Current definition index.
        total (int, optional): Total number of definitions.
    Returns:
        str: Formatted HTML message.
    """
    # Clean up the text - Urban Dictionary uses [brackets] for links
    definition = definition.replace('[', '').replace(']', '')
    example = example.replace('[', '').replace(']', '')
    # Escape any HTML that might be in the original text
    term = html.escape(term)
    author = html.escape(author)
    # Build the message
    header = f"📖 Urban Dictionary: {term}"
    if index is not None and total is not None:
        header += f" (Definition {index}/{total})"
    message = f"""{header}
Definition:
{definition}
"""
    if example and example.strip():
        message += f"""
Example:
{example}
"""
    message += f"""
Author: {author} | 👍 {thumbs_up} 👎 {thumbs_down}
View on Urban Dictionary
"""
    return message
async def handle_command(room, message, bot, prefix, config):
    """
    Function to handle the !ud (Urban Dictionary) command.
    Args:
        room (Room): The Matrix room where the command was invoked.
        message (RoomMessage): The message object containing the command.
        bot (Bot): The bot object.
        prefix (str): The command prefix.
        config (dict): Configuration parameters.
    Returns:
        None
    """
    match = botlib.MessageMatch(room, message, bot, prefix)
    if match.is_not_from_this_bot() and match.prefix() and match.command("ud"):
        logging.info("Received !ud command")
        args = match.args()
        try:
            # Case 1: No arguments - get random definition
            if len(args) == 0:
                logging.info("Fetching random Urban Dictionary definition")
                response = requests.get(RANDOM_API_URL, timeout=10)
                response.raise_for_status()
                data = response.json()
                if not data.get('list'):
                    await bot.api.send_text_message(room.room_id, "No random definition found.")
                    return
                # Get first random entry
                entry = data['list'][0]
                formatted = format_definition(
                    term=entry['word'],
                    definition=entry['definition'],
                    example=entry.get('example', ''),
                    author=entry['author'],
                    thumbs_up=entry['thumbs_up'],
                    thumbs_down=entry['thumbs_down'],
                    permalink=entry['permalink']
                )
                await bot.api.send_markdown_message(room.room_id, formatted)
                logging.info(f"Sent random definition: {entry['word']}")
                return
            # Case 2: One or more arguments - search for term
            # Check if last argument is a number (definition index)
            index = None
            search_term = ' '.join(args)
            if args[-1].isdigit():
                index = int(args[-1])
                search_term = ' '.join(args[:-1])
            if not search_term:
                await bot.api.send_text_message(
                    room.room_id,
                    "Usage: !ud [term] [index]\nExamples:\n  !ud - random definition\n  !ud yeet - first definition of 'yeet'\n  !ud yeet 2 - second definition of 'yeet'"
                )
                return
            logging.info(f"Searching Urban Dictionary for: {search_term}")
            params = {'term': search_term}
            response = requests.get(URBAN_API_URL, params=params, timeout=10)
            response.raise_for_status()
            data = response.json()
            definitions = data.get('list', [])
            if not definitions:
                await bot.api.send_text_message(
                    room.room_id,
                    f"No definition found for '{search_term}'"
                )
                logging.info(f"No definition found for: {search_term}")
                return
            total = len(definitions)
            # If no index specified, use first definition
            if index is None:
                index = 1
            # Validate index
            if index < 1 or index > total:
                await bot.api.send_text_message(
                    room.room_id,
                    f"Invalid index. '{search_term}' has {total} definition(s). Use !ud {search_term} [1-{total}]"
                )
                return
            # Get the requested definition (convert to 0-based index)
            entry = definitions[index - 1]
            formatted = format_definition(
                term=entry['word'],
                definition=entry['definition'],
                example=entry.get('example', ''),
                author=entry['author'],
                thumbs_up=entry['thumbs_up'],
                thumbs_down=entry['thumbs_down'],
                permalink=entry['permalink'],
                index=index,
                total=total
            )
            await bot.api.send_markdown_message(room.room_id, formatted)
            logging.info(f"Sent definition {index}/{total} for: {search_term}")
        except requests.exceptions.Timeout:
            await bot.api.send_text_message(
                room.room_id,
                "Request timed out. Urban Dictionary may be slow or unavailable."
            )
            logging.error("Urban Dictionary API timeout")
        except requests.exceptions.RequestException as e:
            await bot.api.send_text_message(
                room.room_id,
                f"Error fetching from Urban Dictionary: {e}"
            )
            logging.error(f"Error fetching from Urban Dictionary: {e}")
        except Exception as e:
            await bot.api.send_text_message(
                room.room_id,
                "An error occurred while processing the Urban Dictionary request."
            )
            logging.error(f"Unexpected error in Urban Dictionary plugin: {e}", exc_info=True)