import { NextResponse } from "next/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { signJwt } from "@open-mercato/shared/lib/auth/jwt";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { refreshSessionRequestSchema } from "@open-mercato/core/modules/auth/data/validators";
import { checkAuthRateLimit } from "@open-mercato/core/modules/auth/lib/rateLimitCheck";
import { buildSafeRedirectResponse, resolveTrustedRedirectBase } from "@open-mercato/core/modules/auth/lib/requestRedirect";
import { sanitizeRedirectPath } from "@open-mercato/core/modules/auth/lib/safeRedirect";
import { readEndpointRateLimitConfig } from "@open-mercato/shared/lib/ratelimit/config";
import { rateLimitErrorSchema } from "@open-mercato/shared/lib/ratelimit/helpers";
import { z } from "zod";
const refreshRateLimitConfig = readEndpointRateLimitConfig("REFRESH", {
  points: 15,
  duration: 60,
  blockDuration: 60,
  keyPrefix: "refresh"
});
const refreshIpRateLimitConfig = readEndpointRateLimitConfig("REFRESH_IP", {
  points: 60,
  duration: 60,
  blockDuration: 60,
  keyPrefix: "refresh-ip"
});
function parseCookie(req, name) {
  const cookie = req.headers.get("cookie") || "";
  const m = cookie.match(new RegExp("(?:^|;\\s*)" + name + "=([^;]+)"));
  return m ? decodeURIComponent(m[1]) : null;
}
function clearStaffAuthCookies(response) {
  response.cookies.set("auth_token", "", {
    httpOnly: true,
    path: "/",
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
    maxAge: 0
  });
  response.cookies.set("session_token", "", {
    httpOnly: true,
    path: "/",
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
    maxAge: 0
  });
  return response;
}
async function GET(req) {
  const url = new URL(req.url);
  const baseUrl = resolveTrustedRedirectBase(req) ?? url.origin;
  const redirectTo = sanitizeRedirectPath(url.searchParams.get("redirect"), baseUrl, "/");
  const token = parseCookie(req, "session_token");
  if (!token) {
    return clearStaffAuthCookies(
      buildSafeRedirectResponse(req, "/login?redirect=" + encodeURIComponent(redirectTo))
    );
  }
  const c = await createRequestContainer();
  const auth = c.resolve("authService");
  const ctx = await auth.refreshFromSessionToken(token);
  if (!ctx) {
    return clearStaffAuthCookies(
      buildSafeRedirectResponse(req, "/login?redirect=" + encodeURIComponent(redirectTo))
    );
  }
  const { user, roles, session } = ctx;
  const jwt = signJwt({ sub: String(user.id), sid: session ? String(session.id) : void 0, tenantId: String(user.tenantId), orgId: String(user.organizationId), email: user.email, roles });
  const res = buildSafeRedirectResponse(req, redirectTo);
  res.cookies.set("auth_token", jwt, { httpOnly: true, path: "/", sameSite: "lax", secure: process.env.NODE_ENV === "production", maxAge: 60 * 60 * 8 });
  return res;
}
async function POST(req) {
  const { translate } = await resolveTranslations();
  let token = null;
  try {
    const body = await req.json();
    const parsed = refreshSessionRequestSchema.safeParse(body);
    if (parsed.success) {
      token = parsed.data.refreshToken;
    }
  } catch {
  }
  const { error: rateLimitError } = await checkAuthRateLimit({
    req,
    ipConfig: refreshIpRateLimitConfig,
    compoundConfig: refreshRateLimitConfig,
    compoundIdentifier: token ?? void 0
  });
  if (rateLimitError) return rateLimitError;
  if (!token) {
    return clearStaffAuthCookies(
      NextResponse.json({
        ok: false,
        error: translate("auth.session.refresh.errors.invalidPayload", "Missing or invalid refresh token")
      }, { status: 400 })
    );
  }
  const c = await createRequestContainer();
  const auth = c.resolve("authService");
  const ctx = await auth.refreshFromSessionToken(token);
  if (!ctx) {
    return clearStaffAuthCookies(
      NextResponse.json({
        ok: false,
        error: translate("auth.session.refresh.errors.invalidToken", "Invalid or expired refresh token")
      }, { status: 401 })
    );
  }
  const { user, roles, session } = ctx;
  const jwt = signJwt({
    sub: String(user.id),
    sid: session ? String(session.id) : void 0,
    tenantId: String(user.tenantId),
    orgId: String(user.organizationId),
    email: user.email,
    roles
  });
  const res = NextResponse.json({
    ok: true,
    accessToken: jwt,
    expiresIn: 60 * 60 * 8
  });
  res.cookies.set("auth_token", jwt, {
    httpOnly: true,
    path: "/",
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
    maxAge: 60 * 60 * 8
  });
  return res;
}
const metadata = {
  GET: { requireAuth: false },
  POST: { requireAuth: false }
};
const refreshQuerySchema = z.object({
  redirect: z.string().optional().describe("Absolute or relative URL to redirect after refresh")
});
const refreshSuccessSchema = z.object({
  ok: z.literal(true),
  accessToken: z.string().describe("New JWT access token"),
  expiresIn: z.number().describe("Token expiration time in seconds")
});
const refreshErrorSchema = z.object({
  ok: z.literal(false),
  error: z.string()
});
const openApi = {
  tag: "Authentication & Accounts",
  summary: "Refresh session token",
  methods: {
    GET: {
      summary: "Refresh auth cookie from session token (browser)",
      description: "Exchanges an existing `session_token` cookie for a fresh JWT auth cookie and redirects the browser.",
      query: refreshQuerySchema,
      responses: [
        { status: 302, description: "Redirect to target location when session is valid", mediaType: "text/html" }
      ]
    },
    POST: {
      summary: "Refresh access token (API/mobile)",
      description: "Exchanges a refresh token for a new JWT access token. Pass the refresh token obtained from login in the request body.",
      requestBody: { schema: refreshSessionRequestSchema, contentType: "application/json" },
      responses: [
        { status: 200, description: "New access token issued", schema: refreshSuccessSchema }
      ],
      errors: [
        { status: 400, description: "Missing refresh token", schema: refreshErrorSchema },
        { status: 401, description: "Invalid or expired token", schema: refreshErrorSchema },
        { status: 429, description: "Too many refresh attempts", schema: rateLimitErrorSchema }
      ]
    }
  }
};
export {
  GET,
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=refresh.js.map
