(function attachMicrosoftEmailHelpers(globalScope) {
  const OPENAI_SENDER_PATTERNS = [
    /openai\.com/i,
    /auth0\.openai\.com/i,
  ];
  const CODE_PATTERN = /\b(\d{6})\b/;
  const GRAPH_SCOPES = 'offline_access https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/User.Read';
  const GRAPH_DEFAULT_SCOPE = 'https://graph.microsoft.com/.default';
  const TOKEN_STRATEGIES = [
    {
      name: 'entra-common-delegated',
      url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
      extraData: { scope: GRAPH_SCOPES },
    },
    {
      name: 'entra-consumers-delegated',
      url: 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token',
      extraData: { scope: GRAPH_SCOPES },
    },
    {
      name: 'entra-common-default',
      url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
      extraData: { scope: GRAPH_DEFAULT_SCOPE },
    },
    {
      name: 'entra-common-outlook',
      url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
      extraData: {},
    },
  ];
  const TRANSPORT_PLANS = [
    {
      transport: 'graph',
      strategyNames: ['entra-common-delegated', 'entra-consumers-delegated', 'entra-common-default'],
    },
    {
      transport: 'outlook',
      strategyNames: ['entra-common-outlook', 'entra-common-delegated', 'entra-consumers-delegated'],
    },
  ];
  const GRAPH_API_BASE = 'https://graph.microsoft.com/v1.0/me/mailFolders';
  const OUTLOOK_API_BASE = 'https://outlook.office.com/api/v2.0/me/mailfolders';

  function getFetchImpl(fetchImpl) {
    const resolved = fetchImpl || globalScope.fetch;
    if (typeof resolved !== 'function') {
      throw new Error('Microsoft email helper requires a fetch implementation.');
    }
    return resolved;
  }

  function resolveTokenStrategy(name) {
    return TOKEN_STRATEGIES.find((item) => item.name === name) || TOKEN_STRATEGIES[0];
  }

  function normalizeMailboxLabel(mailbox = 'INBOX') {
    return /^junk(?:\s*e-?mail|\s*email)?$/i.test(String(mailbox || '').trim()) ? 'Junk' : 'INBOX';
  }

  function normalizeMailboxId(mailbox = 'INBOX') {
    return normalizeMailboxLabel(mailbox) === 'Junk' ? 'junkemail' : 'inbox';
  }

  function normalizeMailboxList(mailboxes) {
    const list = Array.isArray(mailboxes) && mailboxes.length ? mailboxes : ['INBOX'];
    return [...new Set(list.map((mailbox) => normalizeMailboxLabel(mailbox)))];
  }

  async function getResponseErrorText(response) {
    const text = await response.text().catch(() => '');
    if (!text) {
      return response.statusText || `HTTP ${response.status}`;
    }
    try {
      const parsed = JSON.parse(text);
      return parsed.error_description || parsed.error?.message || parsed.error || parsed.message || text;
    } catch {
      return text;
    }
  }

  async function exchangeRefreshToken(clientId, refreshToken, options = {}) {
    const fetchImpl = getFetchImpl(options.fetchImpl);
    const strategy = resolveTokenStrategy(options.strategyName);
    const body = new URLSearchParams({
      client_id: clientId,
      grant_type: 'refresh_token',
      refresh_token: refreshToken,
      ...(strategy.extraData || {}),
    });
    const response = await fetchImpl(strategy.url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: body.toString(),
      signal: options.signal,
    });

    if (!response.ok) {
      throw new Error(`${strategy.name}: ${await getResponseErrorText(response)}`);
    }

    const data = await response.json();
    if (!data.access_token) {
      throw new Error(`${strategy.name}: token response missing access_token`);
    }

    return {
      ...data,
      tokenStrategy: strategy.name,
    };
  }

  async function fetchGraphMessages(accessToken, options = {}) {
    const fetchImpl = getFetchImpl(options.fetchImpl);
    const mailbox = normalizeMailboxLabel(options.mailbox);
    const top = Math.max(1, Math.min(Number(options.top) || 5, 30));
    const url = `${GRAPH_API_BASE}/${normalizeMailboxId(mailbox)}/messages?$top=${encodeURIComponent(top)}&$select=id,internetMessageId,subject,from,bodyPreview,receivedDateTime&$orderby=receivedDateTime desc`;
    const response = await fetchImpl(url, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        Authorization: `Bearer ${accessToken}`,
      },
      signal: options.signal,
    });

    if (!response.ok) {
      throw new Error(`graph: ${await getResponseErrorText(response)}`);
    }

    const payload = await response.json();
    return Array.isArray(payload?.value) ? payload.value : [];
  }

  async function fetchOutlookMessages(accessToken, options = {}) {
    const fetchImpl = getFetchImpl(options.fetchImpl);
    const mailbox = normalizeMailboxLabel(options.mailbox);
    const top = Math.max(1, Math.min(Number(options.top) || 5, 30));
    const url = `${OUTLOOK_API_BASE}/${normalizeMailboxId(mailbox)}/messages?$top=${encodeURIComponent(top)}&$select=Id,Subject,From,BodyPreview,Body,ReceivedDateTime&$orderby=ReceivedDateTime desc`;
    const response = await fetchImpl(url, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        Authorization: `Bearer ${accessToken}`,
      },
      signal: options.signal,
    });

    if (!response.ok) {
      throw new Error(`outlook: ${await getResponseErrorText(response)}`);
    }

    const payload = await response.json();
    return Array.isArray(payload?.value) ? payload.value : [];
  }

  function normalizeMessage(message, mailbox = 'INBOX') {
    const sender = message?.From || message?.from || {};
    const emailAddress = sender?.EmailAddress || sender?.emailAddress || {};
    return {
      mailbox: normalizeMailboxLabel(mailbox || message?.mailbox),
      from: {
        emailAddress: {
          address: String(emailAddress?.Address || emailAddress?.address || '').trim(),
          name: String(emailAddress?.Name || emailAddress?.name || '').trim(),
        },
      },
      subject: String(message?.Subject || message?.subject || '').trim(),
      receivedDateTime: String(message?.ReceivedDateTime || message?.receivedDateTime || '').trim(),
      bodyPreview: String(message?.BodyPreview || message?.bodyPreview || '').trim(),
      body: {
        content: String(message?.Body?.Content || message?.body?.content || '').trim(),
      },
      id: String(message?.Id || message?.id || message?.internetMessageId || '').trim(),
    };
  }

  function normalizeFilterValue(value) {
    return String(value || '').trim().toLowerCase();
  }

  function getMessageSender(message) {
    return String(
      message?.from?.emailAddress?.address
      || message?.sender?.emailAddress?.address
      || ''
    ).trim();
  }

  function getMessageTimestamp(message) {
    const value = Date.parse(message?.receivedDateTime || message?.createdDateTime || '');
    return Number.isFinite(value) ? value : 0;
  }

  function getMessageSearchText(message) {
    return [
      message?.subject,
      message?.bodyPreview,
      message?.body?.content,
      getMessageSender(message),
    ]
      .map((value) => String(value || ''))
      .join('\n');
  }

  function isOpenAiMessage(message) {
    const sender = getMessageSender(message);
    if (OPENAI_SENDER_PATTERNS.some((pattern) => pattern.test(sender))) {
      return true;
    }

    const searchText = getMessageSearchText(message);
    return OPENAI_SENDER_PATTERNS.some((pattern) => pattern.test(searchText));
  }

  function extractVerificationCodeFromMessages(messages, options = {}) {
    const filterAfterTimestamp = Number(options.filterAfterTimestamp || 0) || 0;
    const senderFilters = (options.senderFilters || []).map(normalizeFilterValue).filter(Boolean);
    const subjectFilters = (options.subjectFilters || []).map(normalizeFilterValue).filter(Boolean);
    const excludedCodes = new Set((options.excludeCodes || []).map((value) => String(value || '').trim()).filter(Boolean));
    const hasExplicitFilters = senderFilters.length > 0 || subjectFilters.length > 0;

    const sortedMessages = (Array.isArray(messages) ? messages : [])
      .map((raw) => normalizeMessage(raw, raw?.mailbox))
      .sort((left, right) => getMessageTimestamp(right) - getMessageTimestamp(left));

    for (const message of sortedMessages) {
      const receivedAt = getMessageTimestamp(message);
      if (receivedAt && receivedAt < filterAfterTimestamp) {
        continue;
      }

      const sender = normalizeFilterValue(getMessageSender(message));
      const subject = normalizeFilterValue(message?.subject);
      const preview = normalizeFilterValue(message?.bodyPreview);
      const searchText = normalizeFilterValue(getMessageSearchText(message));
      const codeMatch = getMessageSearchText(message).match(CODE_PATTERN);
      const code = codeMatch?.[1] || '';
      if (!code || excludedCodes.has(code)) {
        continue;
      }

      if (!hasExplicitFilters && !isOpenAiMessage(message)) {
        continue;
      }

      const senderMatched = senderFilters.length === 0
        ? true
        : senderFilters.some((filter) => sender.includes(filter) || preview.includes(filter) || searchText.includes(filter));
      const subjectMatched = subjectFilters.length === 0
        ? true
        : subjectFilters.some((filter) => subject.includes(filter) || preview.includes(filter) || searchText.includes(filter));
      if (!senderMatched && !subjectMatched) {
        continue;
      }

      return {
        code,
        emailTimestamp: receivedAt || Date.now(),
        messageId: message?.id || null,
        sender: getMessageSender(message),
        subject: String(message?.subject || ''),
        mailbox: message?.mailbox || 'INBOX',
        message,
      };
    }

    return null;
  }

  async function fetchMicrosoftMailboxMessages(options = {}) {
    const {
      clientId,
      refreshToken,
      mailbox = 'INBOX',
      top = 5,
      fetchImpl,
      signal,
      log = null,
    } = options;

    if (!refreshToken) {
      throw new Error('Microsoft refresh token is empty.');
    }
    if (!clientId) {
      throw new Error('Microsoft client_id is empty.');
    }

    const errors = [];
    for (const plan of TRANSPORT_PLANS) {
      for (const strategyName of plan.strategyNames) {
        try {
          const tokenData = await exchangeRefreshToken(clientId, refreshToken, {
            fetchImpl,
            signal,
            strategyName,
          });
          const rawMessages = plan.transport === 'graph'
            ? await fetchGraphMessages(tokenData.access_token, { mailbox, top, fetchImpl, signal })
            : await fetchOutlookMessages(tokenData.access_token, { mailbox, top, fetchImpl, signal });

          return {
            tokenData,
            nextRefreshToken: String(tokenData?.refresh_token || '').trim(),
            tokenStrategy: strategyName,
            transport: plan.transport,
            mailbox: normalizeMailboxLabel(mailbox),
            messages: rawMessages.map((message) => normalizeMessage(message, mailbox)),
          };
        } catch (error) {
          const message = error?.message || String(error);
          errors.push(`${plan.transport}/${strategyName}: ${message}`);
          if (typeof log === 'function') {
            log(`mailbox=${normalizeMailboxLabel(mailbox)} ${plan.transport}/${strategyName} failed: ${message}`);
          }
        }
      }
    }

    throw new Error(`Microsoft mailbox request failed: ${errors.join(' | ')}`);
  }

  function delay(timeoutMs, signal) {
    if (timeoutMs <= 0) {
      return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        cleanup();
        resolve();
      }, timeoutMs);
      const onAbort = () => {
        cleanup();
        reject(signal.reason || new Error('Aborted'));
      };
      const cleanup = () => {
        clearTimeout(timer);
        signal?.removeEventListener('abort', onAbort);
      };

      if (signal?.aborted) {
        cleanup();
        reject(signal.reason || new Error('Aborted'));
        return;
      }

      signal?.addEventListener('abort', onAbort, { once: true });
    });
  }

  async function fetchMicrosoftVerificationCode(options = {}) {
    const {
      token,
      refreshToken,
      clientId,
      maxRetries = 3,
      retryDelayMs = 10000,
      top = 5,
      log = null,
      filterAfterTimestamp = 0,
      senderFilters = [],
      subjectFilters = [],
      excludeCodes = [],
      mailboxes = ['INBOX'],
      fetchImpl,
      signal,
    } = options;

    let workingRefreshToken = String(refreshToken || token || '').trim();
    if (!workingRefreshToken) {
      throw new Error('Microsoft refresh token is empty.');
    }
    if (!clientId) {
      throw new Error('Microsoft client_id is empty.');
    }

    const normalizedMailboxes = normalizeMailboxList(mailboxes);
    let lastError = null;

    for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
      try {
        const collectedMessages = [];
        for (const mailbox of normalizedMailboxes) {
          const result = await fetchMicrosoftMailboxMessages({
            clientId,
            refreshToken: workingRefreshToken,
            mailbox,
            top,
            fetchImpl,
            signal,
            log,
          });
          if (result.nextRefreshToken) {
            workingRefreshToken = result.nextRefreshToken;
          }
          collectedMessages.push(...result.messages);
        }

        const match = extractVerificationCodeFromMessages(collectedMessages, {
          filterAfterTimestamp,
          senderFilters,
          subjectFilters,
          excludeCodes,
        });
        if (match) {
          return {
            ...match,
            nextRefreshToken: workingRefreshToken,
            messages: collectedMessages,
          };
        }

        lastError = new Error('No matching Microsoft verification email found.');
      } catch (error) {
        lastError = error;
      }

      if (attempt < maxRetries) {
        if (typeof log === 'function') {
          log(`attempt ${attempt}/${maxRetries} found no matching Microsoft mail, retrying...`);
        }
        await delay(retryDelayMs, signal);
      }
    }

    throw lastError || new Error('No matching Microsoft verification email found.');
  }

  const api = {
    CODE_PATTERN,
    exchangeRefreshToken,
    extractVerificationCodeFromMessages,
    fetchGraphMessages,
    fetchMicrosoftMailboxMessages,
    fetchMicrosoftVerificationCode,
    fetchOutlookMessages,
    getMessageSender,
    getMessageTimestamp,
    isOpenAiMessage,
    normalizeMailboxId,
    normalizeMailboxLabel,
    normalizeMessage,
  };

  globalScope.MultiPageMicrosoftEmail = api;

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = api;
  }
})(typeof globalThis !== 'undefined' ? globalThis : this);
