"""
Email Tools

IMAP reading and SMTP sending tools.
"""

import email
import email.mime.text
import email.mime.multipart
import imaplib
import logging
import smtplib
from typing import Dict, Any

from .base import BaseTool, ToolMetadata, ToolParameter, ToolPermission, ToolExecutionContext, ToolResult

logger = logging.getLogger(__name__)


class ReadEmailTool(BaseTool):
    """Read emails via IMAP."""

    def get_metadata(self) -> ToolMetadata:
        return ToolMetadata(
            name="READ_EMAIL",
            description="Read emails from an IMAP mailbox. Returns subject, sender, date, and body.",
            category="network",
            parameters=[
                ToolParameter("host", "string", "IMAP server host", required=True),
                ToolParameter("username", "string", "Email username", required=True),
                ToolParameter("password", "string", "Email password", required=True),
                ToolParameter("folder", "string", "Mailbox folder", default="INBOX"),
                ToolParameter("count", "integer", "Number of emails to fetch", default=5),
                ToolParameter("search", "string", "IMAP search query", default="ALL"),
                ToolParameter("port", "integer", "IMAP port", default=993),
            ],
            permissions=[ToolPermission.NETWORK],
        )

    def execute(self, params: Dict[str, Any], context: ToolExecutionContext) -> ToolResult:
        host = params["host"]
        username = params["username"]
        password = params["password"]
        folder = params.get("folder", "INBOX")
        count = params.get("count", 5)
        search_query = params.get("search", "ALL")
        port = params.get("port", 993)

        try:
            mail = imaplib.IMAP4_SSL(host, port)
            mail.login(username, password)
            mail.select(folder)

            _, data = mail.search(None, search_query)
            ids = data[0].split()
            ids = ids[-count:]  # Last N emails

            emails = []
            for eid in reversed(ids):
                _, msg_data = mail.fetch(eid, "(RFC822)")
                msg = email.message_from_bytes(msg_data[0][1])

                # Extract body
                body = ""
                if msg.is_multipart():
                    for part in msg.walk():
                        if part.get_content_type() == "text/plain":
                            body = part.get_payload(decode=True).decode("utf-8", errors="replace")
                            break
                else:
                    body = msg.get_payload(decode=True).decode("utf-8", errors="replace")

                emails.append(
                    f"From: {msg['From']}\n"
                    f"Subject: {msg['Subject']}\n"
                    f"Date: {msg['Date']}\n"
                    f"Body: {body[:500]}\n"
                    f"---"
                )

            mail.logout()
            output = "\n".join(emails) if emails else "No emails found"
            return ToolResult.ok(output, email_count=len(emails))

        except Exception as e:
            return ToolResult.fail(f"Email error: {e}")


class SendEmailTool(BaseTool):
    """Send emails via SMTP."""

    def get_metadata(self) -> ToolMetadata:
        return ToolMetadata(
            name="SEND_EMAIL",
            description="Send an email via SMTP.",
            category="network",
            parameters=[
                ToolParameter("host", "string", "SMTP server host", required=True),
                ToolParameter("username", "string", "SMTP username", required=True),
                ToolParameter("password", "string", "SMTP password", required=True),
                ToolParameter("to", "string", "Recipient email", required=True),
                ToolParameter("subject", "string", "Email subject", required=True),
                ToolParameter("body", "string", "Email body", required=True),
                ToolParameter("from_addr", "string", "Sender address (defaults to username)"),
                ToolParameter("port", "integer", "SMTP port", default=587),
                ToolParameter("html", "boolean", "Send as HTML", default=False),
            ],
            permissions=[ToolPermission.NETWORK],
        )

    def execute(self, params: Dict[str, Any], context: ToolExecutionContext) -> ToolResult:
        host = params["host"]
        username = params["username"]
        password = params["password"]
        to_addr = params["to"]
        subject = params["subject"]
        body = params["body"]
        from_addr = params.get("from_addr", username)
        port = params.get("port", 587)
        is_html = params.get("html", False)

        try:
            msg = email.mime.multipart.MIMEMultipart()
            msg["From"] = from_addr
            msg["To"] = to_addr
            msg["Subject"] = subject

            content_type = "html" if is_html else "plain"
            msg.attach(email.mime.text.MIMEText(body, content_type))

            with smtplib.SMTP(host, port) as server:
                server.starttls()
                server.login(username, password)
                server.send_message(msg)

            return ToolResult.ok(f"Email sent to {to_addr}")

        except Exception as e:
            return ToolResult.fail(f"Email error: {e}")


def get_all_tools():
    return [ReadEmailTool, SendEmailTool]
