import {
  optionalISODateTime,
  optionalString,
  optionalTrimmedString,
  requireStringField,
  resolveWorkspaceSlug
} from "./tool-helpers.mjs";

const EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

function parseAddressString(rawAddress, fieldName, index) {
  const value = String(rawAddress || "").trim();
  if (!value) {
    throw new Error(`${fieldName}[${index}] must be a non-empty email or "Name <email>"`);
  }

  const match = value.match(/^(.*?)<([^>]+)>$/);
  const name = match ? match[1].trim() : "";
  const email = (match ? match[2] : value).trim().toLowerCase();
  if (!EMAIL_PATTERN.test(email)) {
    throw new Error(`${fieldName}[${index}] must include a valid email address`);
  }
  return name ? { name, email } : { email };
}

function parseAddressObject(rawAddress, fieldName, index) {
  if (!rawAddress || typeof rawAddress !== "object" || Array.isArray(rawAddress)) {
    throw new Error(`${fieldName}[${index}] must be a string or object`);
  }
  const email = String(rawAddress.email || "").trim().toLowerCase();
  if (!EMAIL_PATTERN.test(email)) {
    throw new Error(`${fieldName}[${index}].email must be a valid email address`);
  }
  const name = optionalTrimmedString(rawAddress.name);
  return name ? { name, email } : { email };
}

function normalizeAddressList(rawValue, fieldName, required) {
  if (rawValue === undefined || rawValue === null || rawValue === "") {
    if (required) {
      throw new Error(`${fieldName} is required`);
    }
    return [];
  }

  let values = [];
  if (typeof rawValue === "string") {
    values = rawValue
      .split(",")
      .map(part => part.trim())
      .filter(Boolean);
  } else if (Array.isArray(rawValue)) {
    values = rawValue;
  } else {
    throw new Error(`${fieldName} must be a comma-separated string or an array`);
  }

  if (required && values.length === 0) {
    throw new Error(`${fieldName} is required`);
  }

  return values.map((item, index) => {
    if (typeof item === "string") {
      return parseAddressString(item, fieldName, index);
    }
    return parseAddressObject(item, fieldName, index);
  });
}

export function createCreateOutgoingMailTool(client, options = {}) {
  const defaultWorkspaceSlug = options.defaultWorkspaceSlug || process.env.PRODUCTIER_WORKSPACE_SLUG_DEFAULT || "";

  return {
    name: "productier_create_outgoing_mail",
    description: "Queue an outgoing email (send now or schedule) in Productier.",
    inputSchema: {
      type: "object",
      properties: {
        workspaceSlug: { type: "string", description: "Workspace slug. Defaults to PRODUCTIER_WORKSPACE_SLUG_DEFAULT." },
        mailboxId: { type: "string", description: "Mailbox id used for delivery." },
        to: {
          description: "Recipients as comma-separated string or array of strings/objects ({email,name}).",
          anyOf: [
            { type: "string" },
            {
              type: "array",
              items: {
                anyOf: [
                  { type: "string" },
                  {
                    type: "object",
                    properties: {
                      email: { type: "string" },
                      name: { type: "string" }
                    },
                    required: ["email"],
                    additionalProperties: false
                  }
                ]
              }
            }
          ]
        },
        cc: {
          description: "Optional recipients as comma-separated string or array of strings/objects ({email,name}).",
          anyOf: [{ type: "string" }, { type: "array" }]
        },
        bcc: {
          description: "Optional recipients as comma-separated string or array of strings/objects ({email,name}).",
          anyOf: [{ type: "string" }, { type: "array" }]
        },
        subject: { type: "string" },
        textBody: { type: "string" },
        htmlBody: { type: "string" },
        scheduledFor: { type: "string", description: "Optional ISO date-time; future values schedule delivery." }
      },
      required: ["mailboxId", "to"],
      additionalProperties: false
    },
    async invoke(rawInput = {}) {
      const workspaceSlug = resolveWorkspaceSlug(rawInput.workspaceSlug, defaultWorkspaceSlug);
      if (!workspaceSlug) {
        throw new Error("workspaceSlug is required (or set PRODUCTIER_WORKSPACE_SLUG_DEFAULT)");
      }

      const mailboxId = requireStringField(rawInput.mailboxId, "mailboxId");
      const to = normalizeAddressList(rawInput.to, "to", true);
      const cc = normalizeAddressList(rawInput.cc, "cc", false);
      const bcc = normalizeAddressList(rawInput.bcc, "bcc", false);
      const subject = optionalString(rawInput.subject);
      const textBody = optionalString(rawInput.textBody);
      const htmlBody = optionalString(rawInput.htmlBody);
      const scheduledFor = optionalISODateTime(rawInput.scheduledFor, "scheduledFor");

      const body = {
        workspaceSlug,
        mailboxId,
        to,
        ...(cc.length ? { cc } : {}),
        ...(bcc.length ? { bcc } : {}),
        ...(subject !== undefined ? { subject } : {}),
        ...(textBody !== undefined ? { textBody } : {}),
        ...(htmlBody !== undefined ? { htmlBody } : {}),
        ...(scheduledFor ? { scheduledFor } : {})
      };

      const response = await client.createOutgoingMail(body);
      return {
        queued: true,
        workspaceSlug,
        mailboxId,
        outgoingMail: response?.data ?? null
      };
    }
  };
}
