import { NextResponse } from "next/server";
import { z } from "zod";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { CustomerRole, CustomerRoleAcl } from "@open-mercato/core/modules/customer_accounts/data/entities";
import { updateRoleAclSchema } from "@open-mercato/core/modules/customer_accounts/data/validators";
import { enforceCommandOptimisticLock } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
import { isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import {
  runCrudMutationGuardAfterSuccess,
  validateCrudMutationGuard
} from "@open-mercato/shared/lib/crud/mutation-guard";
const metadata = {};
const ROLE_RESOURCE_KIND = "customer_accounts.role";
async function PUT(req, { params }) {
  const auth = await getAuthFromRequest(req);
  if (!auth || !auth.tenantId) {
    return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
  }
  const tenantId = auth.tenantId;
  const container = await createRequestContainer();
  const rbacService = container.resolve("rbacService");
  const hasAccess = await rbacService.userHasAllFeatures(auth.sub, ["customer_accounts.roles.manage"], { tenantId, organizationId: auth.orgId });
  if (!hasAccess) {
    return NextResponse.json({ ok: false, error: "Insufficient permissions" }, { status: 403 });
  }
  let body;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ ok: false, error: "Invalid request body" }, { status: 400 });
  }
  const parsed = updateRoleAclSchema.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json({ ok: false, error: "Validation failed", details: parsed.error.flatten().fieldErrors }, { status: 400 });
  }
  const em = container.resolve("em");
  const role = await em.findOne(CustomerRole, {
    id: params.id,
    tenantId,
    deletedAt: null
  });
  if (!role) {
    return NextResponse.json({ ok: false, error: "Role not found" }, { status: 404 });
  }
  try {
    enforceCommandOptimisticLock({
      resourceKind: ROLE_RESOURCE_KIND,
      resourceId: role.id,
      current: role.updatedAt ?? null,
      request: req
    });
  } catch (err) {
    if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status });
    throw err;
  }
  const guardResult = await validateCrudMutationGuard(container, {
    tenantId,
    organizationId: auth.orgId,
    userId: auth.sub,
    resourceKind: ROLE_RESOURCE_KIND,
    resourceId: role.id,
    operation: "update",
    requestMethod: req.method,
    requestHeaders: req.headers,
    mutationPayload: parsed.data
  });
  if (guardResult && !guardResult.ok) {
    return NextResponse.json(guardResult.body, { status: guardResult.status });
  }
  const acl = await em.findOne(CustomerRoleAcl, {
    role: role.id,
    tenantId
  });
  if (acl) {
    await em.nativeUpdate(CustomerRoleAcl, { id: acl.id }, {
      featuresJson: parsed.data.features,
      isPortalAdmin: parsed.data.isPortalAdmin ?? acl.isPortalAdmin
    });
  } else {
    const newAcl = em.create(CustomerRoleAcl, {
      role,
      tenantId,
      featuresJson: parsed.data.features,
      isPortalAdmin: parsed.data.isPortalAdmin ?? false,
      createdAt: /* @__PURE__ */ new Date()
    });
    em.persist(newAcl);
    await em.flush();
  }
  const nextUpdatedAt = /* @__PURE__ */ new Date();
  await em.nativeUpdate(CustomerRole, { id: role.id }, { updatedAt: nextUpdatedAt });
  const customerRbacService = container.resolve("customerRbacService");
  await customerRbacService.invalidateRoleCache(role.id);
  if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
    await runCrudMutationGuardAfterSuccess(container, {
      tenantId,
      organizationId: auth.orgId,
      userId: auth.sub,
      resourceKind: ROLE_RESOURCE_KIND,
      resourceId: role.id,
      operation: "update",
      requestMethod: req.method,
      requestHeaders: req.headers,
      metadata: guardResult.metadata ?? null
    });
  }
  return NextResponse.json({ ok: true, updatedAt: nextUpdatedAt.toISOString() });
}
const successSchema = z.object({ ok: z.literal(true), updatedAt: z.string().datetime() });
const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
const methodDoc = {
  summary: "Update customer role ACL (admin)",
  description: "Updates the ACL (features and portal admin flag) for a customer role. Invalidates RBAC cache after update.",
  tags: ["Customer Accounts Admin"],
  requestBody: { schema: updateRoleAclSchema },
  responses: [{ status: 200, description: "ACL updated", schema: successSchema }],
  errors: [
    { status: 400, description: "Validation failed", schema: errorSchema },
    { status: 401, description: "Not authenticated", schema: errorSchema },
    { status: 403, description: "Insufficient permissions", schema: errorSchema },
    { status: 404, description: "Role not found", schema: errorSchema },
    { status: 409, description: "Stale ACL write (optimistic-lock conflict)", schema: errorSchema }
  ]
};
const openApi = {
  summary: "Update customer role ACL (admin)",
  pathParams: z.object({ id: z.string().uuid() }),
  methods: { PUT: methodDoc }
};
export {
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=acl.js.map
