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

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

function normalizePort(rawValue, fieldName, fallback) {
  if (rawValue === undefined || rawValue === null || rawValue === "") {
    return fallback;
  }
  const parsed = Number.parseInt(String(rawValue), 10);
  if (Number.isNaN(parsed) || parsed < 1 || parsed > 65535) {
    throw new Error(`${fieldName} must be an integer between 1 and 65535`);
  }
  return parsed;
}

function normalizeBoolean(rawValue, fieldName, fallback) {
  if (rawValue === undefined || rawValue === null || rawValue === "") {
    return fallback;
  }
  if (typeof rawValue === "boolean") {
    return rawValue;
  }

  const value = String(rawValue).trim().toLowerCase();
  if (["1", "true", "yes", "on"].includes(value)) {
    return true;
  }
  if (["0", "false", "no", "off"].includes(value)) {
    return false;
  }
  throw new Error(`${fieldName} must be a boolean`);
}

function validateEmail(email, fieldName) {
  if (!EMAIL_PATTERN.test(email)) {
    throw new Error(`${fieldName} must be a valid email address`);
  }
}

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

  return {
    name: "productier_connect_mailbox",
    description: "Connect an IMAP/SMTP mailbox to a Productier workspace.",
    inputSchema: {
      type: "object",
      properties: {
        workspaceSlug: { type: "string", description: "Workspace slug. Defaults to PRODUCTIER_WORKSPACE_SLUG_DEFAULT." },
        label: { type: "string", description: "Optional mailbox label." },
        email: { type: "string", description: "Mailbox sender email address." },
        displayName: { type: "string", description: "Optional sender display name." },
        imapHost: { type: "string", description: "IMAP host (required)." },
        imapPort: { type: "integer", minimum: 1, maximum: 65535, description: "IMAP port, default 993." },
        imapUsername: { type: "string", description: "Optional IMAP username (defaults to email)." },
        imapPassword: { type: "string", description: "IMAP password (required)." },
        imapUseTls: { type: "boolean", description: "Use TLS for IMAP, default true." },
        smtpHost: { type: "string", description: "SMTP host (required)." },
        smtpPort: { type: "integer", minimum: 1, maximum: 65535, description: "SMTP port, default 587." },
        smtpUsername: { type: "string", description: "Optional SMTP username (defaults to IMAP username)." },
        smtpPassword: { type: "string", description: "Optional SMTP password (blank reuses IMAP password)." },
        smtpUseTls: { type: "boolean", description: "Use TLS for SMTP, default true." }
      },
      required: ["email", "imapHost", "imapPassword", "smtpHost"],
      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 email = requireStringField(rawInput.email, "email").toLowerCase();
      validateEmail(email, "email");

      const imapHost = requireStringField(rawInput.imapHost, "imapHost");
      const imapPassword = requireStringField(rawInput.imapPassword, "imapPassword");
      const smtpHost = requireStringField(rawInput.smtpHost, "smtpHost");

      const label = optionalTrimmedString(rawInput.label);
      const displayName = optionalTrimmedString(rawInput.displayName);
      const imapUsername = optionalTrimmedString(rawInput.imapUsername);
      const smtpUsername = optionalTrimmedString(rawInput.smtpUsername);
      const smtpPassword = optionalTrimmedString(rawInput.smtpPassword);
      const imapPort = normalizePort(rawInput.imapPort, "imapPort", 993);
      const smtpPort = normalizePort(rawInput.smtpPort, "smtpPort", 587);
      const imapUseTls = normalizeBoolean(rawInput.imapUseTls, "imapUseTls", true);
      const smtpUseTls = normalizeBoolean(rawInput.smtpUseTls, "smtpUseTls", true);

      const body = {
        workspaceSlug,
        email,
        imapHost,
        imapPort,
        imapPassword,
        imapUseTls,
        smtpHost,
        smtpPort,
        smtpUseTls,
        ...(label ? { label } : {}),
        ...(displayName ? { displayName } : {}),
        ...(imapUsername ? { imapUsername } : {}),
        ...(smtpUsername ? { smtpUsername } : {}),
        ...(smtpPassword ? { smtpPassword } : {})
      };

      const response = await client.connectMailbox(body);
      return {
        connected: true,
        workspaceSlug,
        mailbox: response?.data ?? null
      };
    }
  };
}
