import { z } from "zod";
import { tool } from "@anthropic-ai/claude-agent-sdk";
import { getAgentState } from "../agent/state.js";
import { GmailEmailClient } from "../email/gmail-email.js";
function ok(text) {
    return { content: [{ type: "text", text }] };
}
function err(text) {
    return { content: [{ type: "text", text }], isError: true };
}
export const manageEmailTool = tool("manage_email", "Manage your email (Gmail). List, search, read, send, reply, and update message state (read/unread/archive).", {
    action: z
        .enum([
        "list",
        "search",
        "read",
        "send",
        "reply",
        "mark_read",
        "mark_unread",
        "archive",
    ])
        .describe("Email action to perform"),
    label: z
        .string()
        .optional()
        .describe("Gmail label to list from (for list)"),
    unread_only: z
        .boolean()
        .optional()
        .describe("Only include unread emails (for list/search)"),
    query: z
        .string()
        .optional()
        .describe("Gmail search query (for search), e.g. 'from:boss subject:(invoice) newer_than:7d'"),
    max_results: z
        .number()
        .int()
        .min(1)
        .max(50)
        .optional()
        .describe("Maximum number of emails to return (for list/search)")
        .default(10),
    message_id: z
        .string()
        .optional()
        .describe("Gmail message ID (for read/reply/mark/archive)")
        .describe("Gmail message ID"),
    to: z
        .string()
        .optional()
        .describe("Recipient email address (for send; optional for reply)"),
    cc: z
        .string()
        .optional()
        .describe("CC recipient email addresses, comma-separated (for send/reply)"),
    bcc: z
        .string()
        .optional()
        .describe("BCC recipient email addresses, comma-separated (for send/reply)"),
    subject: z
        .string()
        .optional()
        .describe("Email subject (for send)"),
    body: z
        .string()
        .optional()
        .describe("Plain-text email body (for send/reply)"),
    html_body: z
        .string()
        .optional()
        .describe("HTML email body (for send/reply). When provided, recipients see rendered HTML with plain-text fallback."),
    attachments: z
        .array(z.object({
        filename: z.string().describe("Attachment filename"),
        mimeType: z.string().optional().describe("MIME type (e.g. 'application/pdf')"),
        localPath: z.string().optional().describe("Absolute path to a local file"),
        base64: z.string().optional().describe("Base64-encoded file content"),
        url: z.string().optional().describe("URL reference (included as a link if file data is unavailable)"),
    }))
        .optional()
        .describe("File attachments (for send/reply). Provide localPath or base64 for each."),
    include_body: z
        .boolean()
        .optional()
        .describe("Include full plain-text body when reading (for read)")
        .default(true),
}, async (args) => {
    try {
        const state = getAgentState();
        const client = new GmailEmailClient(state.config);
        switch (args.action) {
            case "list": {
                const emails = await client.listEmails({
                    label: args.label ?? "INBOX",
                    unreadOnly: args.unread_only ?? false,
                    maxResults: args.max_results,
                });
                if (emails.length === 0)
                    return ok("No emails found.");
                const lines = emails.map((m) => {
                    const from = m.from;
                    const subject = m.subject;
                    const date = m.date;
                    const unread = m.labels?.includes("UNREAD") ? "[UNREAD] " : "";
                    return `- [${m.id}] ${unread}${date} | ${from} | ${subject}`;
                });
                return ok(`Found ${emails.length} email(s):\n${lines.join("\n")}`);
            }
            case "search": {
                if (!args.query)
                    return err("Error: query is required for search");
                const emails = await client.listEmails({
                    label: args.label ?? "INBOX",
                    unreadOnly: args.unread_only ?? false,
                    query: args.query,
                    maxResults: args.max_results,
                });
                if (emails.length === 0)
                    return ok("No matching emails found.");
                const lines = emails.map((m) => {
                    const from = m.from;
                    const subject = m.subject;
                    const date = m.date;
                    const unread = m.labels?.includes("UNREAD") ? "[UNREAD] " : "";
                    return `- [${m.id}] ${unread}${date} | ${from} | ${subject}`;
                });
                return ok(`Found ${emails.length} email(s):\n${lines.join("\n")}`);
            }
            case "read": {
                if (!args.message_id)
                    return err("Error: message_id is required for read");
                const msg = await client.getEmail(args.message_id);
                const headerLines = [];
                headerLines.push(`ID: ${msg.id}`);
                if (msg.threadId)
                    headerLines.push(`Thread: ${msg.threadId}`);
                if (msg.date)
                    headerLines.push(`Date: ${msg.date}`);
                if (msg.from)
                    headerLines.push(`From: ${msg.from}`);
                if (msg.to)
                    headerLines.push(`To: ${msg.to}`);
                if (msg.subject)
                    headerLines.push(`Subject: ${msg.subject}`);
                if (msg.labels?.length)
                    headerLines.push(`Labels: ${msg.labels.join(", ")}`);
                const parts = [];
                parts.push(headerLines.join("\n"));
                parts.push("");
                parts.push(`Snippet: ${msg.snippet}`);
                if (args.include_body && msg.bodyText) {
                    parts.push("\n---\nBody:\n" + msg.bodyText);
                }
                return ok(parts.join("\n"));
            }
            case "send": {
                if (!args.to || !args.subject || !args.body) {
                    return err("Error: to, subject, and body are required for send");
                }
                const res = await client.sendEmail({
                    to: args.to,
                    cc: args.cc,
                    bcc: args.bcc,
                    subject: args.subject,
                    body: args.body,
                    htmlBody: args.html_body,
                    attachments: args.attachments?.map((a) => ({
                        type: "file",
                        filename: a.filename,
                        mimeType: a.mimeType,
                        localPath: a.localPath,
                        base64: a.base64,
                        url: a.url,
                    })),
                });
                return ok(`Email sent. Message ID: ${res.id ?? "(unknown)"}`);
            }
            case "reply": {
                if (!args.message_id || !args.body) {
                    return err("Error: message_id and body are required for reply");
                }
                const res = await client.reply({
                    messageId: args.message_id,
                    to: args.to,
                    cc: args.cc,
                    bcc: args.bcc,
                    body: args.body,
                    htmlBody: args.html_body,
                    attachments: args.attachments?.map((a) => ({
                        type: "file",
                        filename: a.filename,
                        mimeType: a.mimeType,
                        localPath: a.localPath,
                        base64: a.base64,
                        url: a.url,
                    })),
                });
                return ok(`Reply sent. Message ID: ${res.id ?? "(unknown)"}`);
            }
            case "mark_read": {
                if (!args.message_id)
                    return err("Error: message_id is required for mark_read");
                await client.markRead(args.message_id);
                return ok(`Marked as read: ${args.message_id}`);
            }
            case "mark_unread": {
                if (!args.message_id)
                    return err("Error: message_id is required for mark_unread");
                await client.markUnread(args.message_id);
                return ok(`Marked as unread: ${args.message_id}`);
            }
            case "archive": {
                if (!args.message_id)
                    return err("Error: message_id is required for archive");
                await client.archive(args.message_id);
                return ok(`Archived: ${args.message_id}`);
            }
            default:
                return err(`Unknown action: ${args.action}`);
        }
    }
    catch (e) {
        return err(`Email operation failed: ${e instanceof Error ? e.message : String(e)}`);
    }
});
//# sourceMappingURL=email.js.map