import os
import re
from typing import Any

import resend
from loguru import logger

from universal_mcp.agents.codeact0.utils import light_copy


def get_context_str(source: Any | list[Any] | dict[str, Any]) -> str:
    """Converts context to a string representation."""
    if not isinstance(source, dict):
        if isinstance(source, list):
            source = {f"doc_{i + 1}": str(doc) for i, doc in enumerate(source)}
        else:
            source = {"content": str(source)}

    return "\n".join(f"<{k}>\n{str(v)}\n</{k}>" for k, v in source.items())


async def ruzo_email_notification(subject: str, html_content: str, to_email: str) -> str:
    """
    Sends an email notification via notifications@ruzo.ai to the specified recipient. Note that this must not be used when the user wants to send an email from their own email account.

    WHEN TO USE:
    - Use this tool ONLY for sending notifications, task completion reports ONLY WHEN asked for/confirmed by the user, when the sender of the email is not required to be the user.
    - Examples: "Send an email report after completing the task..."

    WHEN NOT TO USE:
    - DO NOT use this for general logging, debugging information, or trivial status updates that should be displayed in the chat.
    - DO NOT use this for conversational responses or asking clarifying questions to the user.
    - DO NOT use this for sending emails on behalf of the user. For such cases, find and search for external email services' functions.

    Args:
        subject: The subject of the email.
        html_content: The HTML content of the email body.
        to_email: The recipient's email address.

    Returns:
        A message indicating success or failure.
    """
    try:
        if not to_email:
            return "Error: Recipient email address is required."

        # Check if html_content contains markdown code blocks
        match = re.search(r"```(?:html)?\s*(.*?)```", html_content, re.DOTALL | re.IGNORECASE)
        if match:
            html_content = match.group(1).strip()

        api_key = os.getenv("RESEND_API_KEY")
        if not api_key:
            return "Error: 'RESEND_API_KEY' environment variable is not set."

        resend.api_key = api_key

        params: resend.Emails.SendParams = {
            "from": "Ruzo <notifications@ruzo.ai>",
            "to": [to_email],
            "subject": subject,
            "html": html_content,
        }

        r = resend.Emails.send(params)
        logger.info(f"Email notification sent: {r} to {to_email}")
        return f"Email notification sent successfully to {to_email}."

    except Exception as e:
        error_msg = f"Failed to send email notification: {e}"
        logger.error(error_msg)
        return error_msg


def smart_print(data: Any) -> None:
    """Prints a dictionary or list of dictionaries with truncated values for display.

    Args:
        data: Either a dictionary with string keys, or a list of such dictionaries.

    Notes:
        - all string values are truncated to MAX_CHARS (default:1000) characters, with the
            number of omitted characters appended, e.g. "abc...(+47 more chars)"
        - sequences are limited to the first 20 items; when truncated, a
            final summary string is appended, e.g. "...(+3 more items)"
        - dictionaries are limited to the first 100 keys; when truncated, an
            extra summary key is added, e.g. "...(+2 more keys)"
    """
    print(light_copy(data))  # noqa: T201
