import { readFileSync } from "fs";
import { resolve } from "path";
function loadEnvFileContent() {
  const candidatePaths = [
    resolve(process.cwd(), "apps/mercato/.env"),
    resolve(process.cwd(), ".env")
  ];
  for (const envPath of candidatePaths) {
    try {
      const content = readFileSync(envPath, "utf-8");
      if (content.trim().length > 0) {
        return content;
      }
    } catch {
      continue;
    }
  }
  return null;
}
function loadEnvValue(key) {
  if (process.env[key]) return process.env[key];
  const content = loadEnvFileContent();
  if (!content) return void 0;
  const match = content.match(new RegExp(`^${key}=(.+)$`, "m"));
  return match?.[1]?.trim();
}
const DEFAULT_CREDENTIALS = {
  superadmin: {
    email: loadEnvValue("OM_INIT_SUPERADMIN_EMAIL") || "superadmin@acme.com",
    password: loadEnvValue("OM_INIT_SUPERADMIN_PASSWORD") || "secret"
  },
  admin: { email: "admin@acme.com", password: "secret" },
  employee: { email: "employee@acme.com", password: "secret" }
};
function decodeJwtClaims(token) {
  const parts = token.split(".");
  if (parts.length < 2) return null;
  try {
    const normalized = parts[1].replace(/-/g, "+").replace(/_/g, "/");
    const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
    const payload = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
    return payload;
  } catch {
    return null;
  }
}
async function acknowledgeGlobalNotices(page) {
  const baseUrl = process.env.BASE_URL || "http://localhost:3000";
  await page.context().addCookies([
    {
      name: "om_demo_notice_ack",
      value: "ack",
      url: baseUrl,
      sameSite: "Lax"
    },
    {
      name: "om_cookie_notice_ack",
      value: "ack",
      url: baseUrl,
      sameSite: "Lax"
    },
    {
      name: "om_feedback_suppress",
      value: "1",
      url: baseUrl,
      sameSite: "Lax"
    },
    {
      name: "om_feedback_shown",
      value: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
      url: baseUrl,
      sameSite: "Lax"
    }
  ]);
}
async function dismissGlobalNoticesIfPresent(page) {
  const cookieAcceptButton = page.getByRole("button", { name: /accept cookies/i }).first();
  if (await cookieAcceptButton.isVisible().catch(() => false)) {
    await cookieAcceptButton.click();
  }
  const demoNotice = page.getByText(/this instance is provided for demo purposes only/i).first();
  if (await demoNotice.isVisible().catch(() => false)) {
    const noticeContainer = demoNotice.locator('xpath=ancestor::div[contains(@class,"pointer-events-auto")]').first();
    const dismissButton = noticeContainer.locator("button").first();
    if (await dismissButton.isVisible().catch(() => false)) {
      await dismissButton.click();
    }
  }
  const feedbackDialog = page.getByRole("dialog", { name: /Talk to Open Mercato team/i }).first();
  if (await feedbackDialog.isVisible().catch(() => false)) {
    const closeButton = feedbackDialog.getByRole("button", { name: /close/i }).first();
    if (await closeButton.isVisible().catch(() => false)) {
      await closeButton.click().catch(() => {
      });
    } else {
      await page.keyboard.press("Escape").catch(() => {
      });
    }
  }
}
async function recoverClientSideErrorPageIfPresent(page) {
  const clientErrorHeading = page.getByRole("heading", { name: /Application error: a client-side exception has occurred/i }).first();
  if (!await clientErrorHeading.isVisible().catch(() => false)) return;
  await page.reload({ waitUntil: "domcontentloaded" });
  await dismissGlobalNoticesIfPresent(page);
}
async function recoverGenericErrorPageIfPresent(page) {
  const errorHeading = page.getByRole("heading", { name: /^Something went wrong$/i }).first();
  if (!await errorHeading.isVisible().catch(() => false)) return;
  const retryButton = page.getByRole("button", { name: /Try again/i }).first();
  if (await retryButton.isVisible().catch(() => false)) {
    await retryButton.click().catch(() => {
    });
    await page.waitForLoadState("domcontentloaded").catch(() => {
    });
    await page.waitForTimeout(500).catch(() => {
    });
  } else {
    await page.reload({ waitUntil: "domcontentloaded" });
  }
  await dismissGlobalNoticesIfPresent(page);
}
function toPathOnly(rawUrl) {
  try {
    const url = new URL(rawUrl);
    return `${url.pathname}${url.search}`;
  } catch {
    return "[unparseable-url]";
  }
}
function toRedactedLocation(rawLocation) {
  if (!rawLocation) return null;
  try {
    const url = new URL(rawLocation, "http://integration.local");
    return `${url.pathname}${url.search}`;
  } catch {
    return "[unparseable-location]";
  }
}
function createAuthNavigationTrace(page) {
  const entries = [];
  const onResponse = (response) => {
    const path = toPathOnly(response.url());
    if (path === "/backend" || path.startsWith("/api/auth/session/refresh")) {
      entries.push({
        path,
        status: response.status(),
        location: toRedactedLocation(response.headers().location)
      });
    }
  };
  page.on("response", onResponse);
  return {
    entries,
    stop: () => page.off("response", onResponse)
  };
}
async function formatLoginDiagnostics(page, role, entries) {
  const cookieNames = Array.from(
    new Set((await page.context().cookies()).map((cookie) => cookie.name))
  ).sort((left, right) => left.localeCompare(right));
  const traceLines = entries.length ? entries.map((entry) => {
    const location = entry.location ? ` -> ${entry.location}` : "";
    return `${entry.status} ${entry.path}${location}`;
  }) : ["none"];
  return [
    `Login diagnostics for role "${role}":`,
    `current URL: ${toPathOnly(page.url())}`,
    `browser cookie names: ${cookieNames.length ? cookieNames.join(", ") : "none"}`,
    "backend/refresh trace:",
    ...traceLines
  ].join("\n");
}
async function throwLoginErrorWithDiagnostics(page, role, entries, error) {
  const message = error instanceof Error ? error.message : String(error);
  throw new Error([
    `Login did not reach backend for role: ${role}.`,
    await formatLoginDiagnostics(page, role, entries),
    `Original error: ${message}`
  ].join("\n"));
}
async function login(page, role = "admin") {
  const authTrace = createAuthNavigationTrace(page);
  try {
    const creds = DEFAULT_CREDENTIALS[role];
    const loginReadySelector = 'form[data-auth-ready="1"]';
    const hasBackendUrl = () => /\/backend(?:\/.*)?$/.test(page.url());
    const waitForBackend = async (timeout) => {
      try {
        await page.waitForURL(/\/backend(?:\/.*)?$/, { timeout });
        return true;
      } catch {
        return hasBackendUrl();
      }
    };
    await acknowledgeGlobalNotices(page);
    const apiLoginForm = new URLSearchParams();
    apiLoginForm.set("email", creds.email);
    apiLoginForm.set("password", creds.password);
    let apiLoginResponse = null;
    for (let retry = 0; retry < 4; retry += 1) {
      apiLoginResponse = await page.request.post("/api/auth/login", {
        headers: {
          "content-type": "application/x-www-form-urlencoded"
        },
        data: apiLoginForm.toString()
      }).catch(() => null);
      if (!apiLoginResponse || apiLoginResponse.status() !== 429) break;
      await new Promise((resolve2) => setTimeout(resolve2, 1e3 * 2 ** retry));
    }
    if (apiLoginResponse?.ok()) {
      const apiLoginBody = await apiLoginResponse.json().catch(() => null);
      const claims = typeof apiLoginBody?.token === "string" ? decodeJwtClaims(apiLoginBody.token) : null;
      const baseUrl = process.env.BASE_URL || "http://localhost:3000";
      const cookies = [];
      if (claims?.tenantId) {
        cookies.push({
          name: "om_selected_tenant",
          value: claims.tenantId,
          url: baseUrl,
          sameSite: "Lax"
        });
      }
      if (claims?.orgId) {
        cookies.push({
          name: "om_selected_org",
          value: claims.orgId,
          url: baseUrl,
          sameSite: "Lax"
        });
      }
      if (cookies.length > 0) {
        await page.context().addCookies(cookies);
      }
      await page.goto("/backend", { waitUntil: "domcontentloaded" });
      if (await waitForBackend(8e3)) return;
    }
    for (let attempt = 0; attempt < 4; attempt += 1) {
      await page.goto("/login", { waitUntil: "domcontentloaded" });
      await dismissGlobalNoticesIfPresent(page);
      await recoverClientSideErrorPageIfPresent(page);
      await recoverGenericErrorPageIfPresent(page);
      await page.waitForSelector(loginReadySelector, { state: "visible", timeout: 3e3 }).catch(() => null);
      if (await page.getByLabel("Email").isVisible().catch(() => false)) break;
      if (attempt === 3) {
        throw new Error(`Login form is unavailable for role: ${role}; current URL: ${page.url()}`);
      }
    }
    await page.getByLabel("Email").fill(creds.email);
    const passwordInput = page.getByLabel("Password", { exact: true }).first();
    if (await passwordInput.isVisible().catch(() => false)) {
      await passwordInput.fill(creds.password);
      await passwordInput.press("Enter");
    } else {
      const submitButton = page.getByRole("button", { name: /login|sign in|continue with sso/i }).first();
      await submitButton.click();
    }
    if (await waitForBackend(7e3)) return;
    const loginForm = page.locator("form").first();
    if (await loginForm.isVisible().catch(() => false)) {
      await loginForm.evaluate((element) => {
        const form = element;
        form.requestSubmit();
      }).catch(() => {
      });
    }
    if (await waitForBackend(5e3)) return;
    const loginButton = page.getByRole("button", { name: /login|sign in|continue with sso/i }).first();
    if (await loginButton.isVisible().catch(() => false)) {
      await loginButton.click({ force: true });
    }
    if (await waitForBackend(8e3)) return;
    throw new Error(`Login did not reach backend for role: ${role}; current URL: ${page.url()}`);
  } catch (error) {
    await throwLoginErrorWithDiagnostics(page, role, authTrace.entries, error);
  } finally {
    authTrace.stop();
  }
}
export {
  DEFAULT_CREDENTIALS,
  login
};
//# sourceMappingURL=auth.js.map
