import { NextResponse } from "next/server";
import { z } from "zod";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { signJwt } from "@open-mercato/shared/lib/auth/jwt";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { User } from "@open-mercato/core/modules/auth/data/entities";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { buildPasswordSchema } from "@open-mercato/shared/lib/auth/passwordPolicy";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("auth").child({ component: "profile" });
const profileResponseSchema = z.object({
  email: z.string().email(),
  roles: z.array(z.string())
});
const passwordSchema = buildPasswordSchema();
const updateSchemaBase = z.object({
  email: z.string().email().optional(),
  currentPassword: z.string().trim().min(1).optional(),
  password: passwordSchema.optional()
});
function buildUpdateSchema(translate) {
  return updateSchemaBase.superRefine((data, ctx) => {
    if (!data.email && !data.password) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: translate(
          "auth.profile.form.errors.emailOrPasswordRequired",
          "Provide an email or password."
        ),
        path: ["email"]
      });
    }
    if (data.password && !data.currentPassword) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: translate(
          "auth.profile.form.errors.currentPasswordRequired",
          "Current password is required."
        ),
        path: ["currentPassword"]
      });
    }
    if (data.currentPassword && !data.password) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        message: translate(
          "auth.profile.form.errors.newPasswordRequired",
          "New password is required."
        ),
        path: ["password"]
      });
    }
  });
}
const updateSchema = buildUpdateSchema((_key, fallback) => fallback);
const profileUpdateResponseSchema = z.object({
  ok: z.literal(true),
  email: z.string().email()
});
const metadata = {
  GET: { requireAuth: true },
  PUT: { requireAuth: true }
};
function buildCommandContext(container, auth, req) {
  return {
    container,
    auth,
    organizationScope: null,
    selectedOrganizationId: auth.orgId ?? null,
    organizationIds: auth.orgId ? [auth.orgId] : null,
    request: req
  };
}
async function GET(req) {
  const { translate } = await resolveTranslations();
  const auth = await getAuthFromRequest(req);
  if (!auth?.sub) {
    return NextResponse.json({ error: translate("api.errors.unauthorized", "Unauthorized") }, { status: 401 });
  }
  try {
    const container = await createRequestContainer();
    const em = container.resolve("em");
    const user = await findOneWithDecryption(
      em,
      User,
      { id: auth.sub, deletedAt: null },
      void 0,
      { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null }
    );
    if (!user) {
      return NextResponse.json({ error: translate("auth.users.form.errors.notFound", "User not found") }, { status: 404 });
    }
    return NextResponse.json({ email: String(user.email), roles: auth.roles ?? [] });
  } catch (err) {
    logger.error("Profile load failed", { err });
    return NextResponse.json({ error: translate("auth.profile.form.errors.load", "Failed to load profile.") }, { status: 400 });
  }
}
async function PUT(req) {
  const { translate } = await resolveTranslations();
  const auth = await getAuthFromRequest(req);
  if (!auth?.sub) {
    return NextResponse.json({ error: translate("api.errors.unauthorized", "Unauthorized") }, { status: 401 });
  }
  try {
    const body = await req.json().catch(() => ({}));
    const parsed = buildUpdateSchema(translate).safeParse(body);
    if (!parsed.success) {
      return NextResponse.json(
        {
          error: translate("auth.profile.form.errors.invalid", "Invalid profile update."),
          issues: parsed.error.issues
        },
        { status: 400 }
      );
    }
    const container = await createRequestContainer();
    const em = container.resolve("em");
    const authService = container.resolve("authService");
    if (parsed.data.password) {
      const user = await findOneWithDecryption(
        em,
        User,
        { id: auth.sub, deletedAt: null },
        void 0,
        { tenantId: auth.tenantId ?? null, organizationId: auth.orgId ?? null }
      );
      if (!user) {
        return NextResponse.json({ error: translate("auth.users.form.errors.notFound", "User not found") }, { status: 404 });
      }
      const currentPassword = parsed.data.currentPassword?.trim() ?? "";
      const isCurrentPasswordValid = await authService.verifyPassword(user, currentPassword);
      if (!isCurrentPasswordValid) {
        const message = translate(
          "auth.profile.form.errors.currentPasswordInvalid",
          "Current password is incorrect."
        );
        return NextResponse.json(
          {
            error: message,
            issues: [{ path: ["currentPassword"], message }]
          },
          { status: 400 }
        );
      }
    }
    const commandBus = container.resolve("commandBus");
    const ctx = buildCommandContext(container, auth, req);
    const { result } = await commandBus.execute(
      "auth.users.update",
      {
        input: {
          id: auth.sub,
          email: parsed.data.email,
          password: parsed.data.password
        },
        ctx
      }
    );
    const roles = await authService.getUserRoles(result, result.tenantId ? String(result.tenantId) : null);
    const jwt = signJwt({
      sub: String(result.id),
      sid: typeof auth.sid === "string" ? auth.sid : void 0,
      tenantId: result.tenantId ? String(result.tenantId) : null,
      orgId: result.organizationId ? String(result.organizationId) : null,
      email: result.email,
      roles
    });
    const res = NextResponse.json({ ok: true, email: String(result.email) });
    res.cookies.set("auth_token", jwt, {
      httpOnly: true,
      path: "/",
      sameSite: "lax",
      secure: process.env.NODE_ENV === "production",
      maxAge: 60 * 60 * 8
    });
    return res;
  } catch (err) {
    if (isCrudHttpError(err)) {
      return NextResponse.json(err.body, { status: err.status });
    }
    logger.error("Profile update failed", { err });
    return NextResponse.json({ error: translate("auth.profile.form.errors.save", "Failed to update profile.") }, { status: 400 });
  }
}
const openApi = {
  tag: "Authentication & Accounts",
  summary: "Profile settings",
  methods: {
    GET: {
      summary: "Get current profile",
      description: "Returns the email address for the signed-in user.",
      responses: [
        { status: 200, description: "Profile payload", schema: profileResponseSchema },
        { status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) },
        { status: 404, description: "User not found", schema: z.object({ error: z.string() }) }
      ]
    },
    PUT: {
      summary: "Update current profile",
      description: "Updates the email address or password for the signed-in user.",
      requestBody: {
        contentType: "application/json",
        schema: updateSchema
      },
      responses: [
        { status: 200, description: "Profile updated", schema: profileUpdateResponseSchema },
        { status: 400, description: "Invalid payload", schema: z.object({ error: z.string() }) },
        { status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) }
      ]
    }
  }
};
export {
  GET,
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
