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, CustomerUserRole } from "@open-mercato/core/modules/customer_accounts/data/entities";
import { updateRoleSchema } from "@open-mercato/core/modules/customer_accounts/data/validators";
import { emitCustomerAccountsEvent } from "@open-mercato/core/modules/customer_accounts/events";
import { enforceCommandOptimisticLockWithGuards } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
import { isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
const metadata = {};
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
async function GET(req, { params }) {
  if (!UUID_RE.test(params.id)) {
    return NextResponse.json({ ok: false, error: "Invalid role ID" }, { status: 400 });
  }
  const auth = await getAuthFromRequest(req);
  if (!auth) {
    return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
  }
  const container = await createRequestContainer();
  const rbacService = container.resolve("rbacService");
  const hasAccess = await rbacService.userHasAllFeatures(auth.sub, ["customer_accounts.view"], { tenantId: auth.tenantId, organizationId: auth.orgId });
  if (!hasAccess) {
    return NextResponse.json({ ok: false, error: "Insufficient permissions" }, { status: 403 });
  }
  const em = container.resolve("em");
  const role = await em.findOne(CustomerRole, {
    id: params.id,
    tenantId: auth.tenantId,
    deletedAt: null
  });
  if (!role) {
    return NextResponse.json({ ok: false, error: "Role not found" }, { status: 404 });
  }
  const acl = await em.findOne(CustomerRoleAcl, {
    role: role.id,
    tenantId: auth.tenantId
  });
  const features = acl && Array.isArray(acl.featuresJson) ? acl.featuresJson : [];
  return NextResponse.json({
    ok: true,
    id: role.id,
    name: role.name,
    slug: role.slug,
    description: role.description || null,
    isDefault: role.isDefault,
    isSystem: role.isSystem,
    customerAssignable: role.customerAssignable,
    createdAt: role.createdAt,
    updatedAt: role.updatedAt || null,
    features
  });
}
async function PUT(req, { params }) {
  const auth = await getAuthFromRequest(req);
  if (!auth) {
    return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
  }
  const container = await createRequestContainer();
  const rbacService = container.resolve("rbacService");
  const hasAccess = await rbacService.userHasAllFeatures(auth.sub, ["customer_accounts.roles.manage"], { tenantId: auth.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 = updateRoleSchema.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: auth.tenantId,
    deletedAt: null
  });
  if (!role) {
    return NextResponse.json({ ok: false, error: "Role not found" }, { status: 404 });
  }
  if (role.isSystem && parsed.data.name !== void 0 && parsed.data.name !== role.name) {
    return NextResponse.json({ ok: false, error: "Cannot change name of a system role" }, { status: 400 });
  }
  try {
    await enforceCommandOptimisticLockWithGuards(container, {
      resourceKind: "customer_accounts.role",
      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 nextUpdatedAt = /* @__PURE__ */ new Date();
  const updates = { updatedAt: nextUpdatedAt };
  if (parsed.data.name !== void 0) updates.name = parsed.data.name;
  if (parsed.data.description !== void 0) updates.description = parsed.data.description;
  if (parsed.data.isDefault !== void 0) updates.isDefault = parsed.data.isDefault;
  if (parsed.data.customerAssignable !== void 0) updates.customerAssignable = parsed.data.customerAssignable;
  await em.nativeUpdate(CustomerRole, { id: role.id }, updates);
  void emitCustomerAccountsEvent("customer_accounts.role.updated", {
    id: role.id,
    name: updates.name || role.name,
    tenantId: auth.tenantId,
    organizationId: auth.orgId
  }).catch(() => void 0);
  return NextResponse.json({ ok: true, updatedAt: nextUpdatedAt.toISOString() });
}
async function DELETE(req, { params }) {
  const auth = await getAuthFromRequest(req);
  if (!auth) {
    return NextResponse.json({ ok: false, error: "Authentication required" }, { status: 401 });
  }
  const container = await createRequestContainer();
  const rbacService = container.resolve("rbacService");
  const hasAccess = await rbacService.userHasAllFeatures(auth.sub, ["customer_accounts.roles.manage"], { tenantId: auth.tenantId, organizationId: auth.orgId });
  if (!hasAccess) {
    return NextResponse.json({ ok: false, error: "Insufficient permissions" }, { status: 403 });
  }
  const em = container.resolve("em");
  const role = await em.findOne(CustomerRole, {
    id: params.id,
    tenantId: auth.tenantId,
    deletedAt: null
  });
  if (!role) {
    return NextResponse.json({ ok: false, error: "Role not found" }, { status: 404 });
  }
  if (role.isDefault) {
    return NextResponse.json({ ok: false, error: "Cannot delete the default role. Set another role as default first." }, { status: 400 });
  }
  try {
    await enforceCommandOptimisticLockWithGuards(container, {
      resourceKind: "customer_accounts.role",
      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 assignedUsersCount = await em.count(CustomerUserRole, {
    role: role.id,
    deletedAt: null
  });
  if (assignedUsersCount > 0) {
    return NextResponse.json({ ok: false, error: `Cannot delete role with ${assignedUsersCount} assigned user(s). Reassign users first.` }, { status: 400 });
  }
  await em.nativeUpdate(CustomerRole, { id: role.id }, { deletedAt: /* @__PURE__ */ new Date() });
  await em.nativeUpdate(CustomerRoleAcl, { role: role.id }, { deletedAt: /* @__PURE__ */ new Date() });
  void emitCustomerAccountsEvent("customer_accounts.role.deleted", {
    id: role.id,
    name: role.name,
    slug: role.slug,
    tenantId: auth.tenantId,
    organizationId: auth.orgId
  }).catch(() => void 0);
  return NextResponse.json({ ok: true });
}
const aclSchema = z.object({
  features: z.array(z.string()),
  isPortalAdmin: z.boolean()
});
const roleDetailSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  slug: z.string(),
  description: z.string().nullable(),
  isDefault: z.boolean(),
  isSystem: z.boolean(),
  customerAssignable: z.boolean(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime().nullable(),
  acl: aclSchema
});
const successSchema = z.object({ ok: z.literal(true) });
const errorSchema = z.object({ ok: z.literal(false), error: z.string() });
const getMethodDoc = {
  summary: "Get customer role detail (admin)",
  description: "Returns full customer role details including ACL features.",
  tags: ["Customer Accounts Admin"],
  responses: [{
    status: 200,
    description: "Role detail with ACL",
    schema: z.object({ ok: z.literal(true), role: roleDetailSchema })
  }],
  errors: [
    { status: 401, description: "Not authenticated", schema: errorSchema },
    { status: 403, description: "Insufficient permissions", schema: errorSchema },
    { status: 404, description: "Role not found", schema: errorSchema }
  ]
};
const putMethodDoc = {
  summary: "Update customer role (admin)",
  description: "Updates a customer role. System roles are protected from name changes.",
  tags: ["Customer Accounts Admin"],
  requestBody: { schema: updateRoleSchema },
  responses: [{ status: 200, description: "Role updated", schema: successSchema }],
  errors: [
    { status: 400, description: "Validation failed or system role restriction", schema: errorSchema },
    { status: 401, description: "Not authenticated", schema: errorSchema },
    { status: 403, description: "Insufficient permissions", schema: errorSchema },
    { status: 404, description: "Role not found", schema: errorSchema }
  ]
};
const deleteMethodDoc = {
  summary: "Delete customer role (admin)",
  description: "Soft deletes a customer role and its ACL. The default role (auto-assigned to new portal users) and roles with assigned users cannot be deleted.",
  tags: ["Customer Accounts Admin"],
  responses: [{ status: 200, description: "Role deleted", schema: successSchema }],
  errors: [
    { status: 400, description: "Default role or has assigned users", schema: errorSchema },
    { status: 401, description: "Not authenticated", schema: errorSchema },
    { status: 403, description: "Insufficient permissions", schema: errorSchema },
    { status: 404, description: "Role not found", schema: errorSchema }
  ]
};
const openApi = {
  summary: "Customer role detail management (admin)",
  pathParams: z.object({ id: z.string().uuid() }),
  methods: {
    GET: getMethodDoc,
    PUT: putMethodDoc,
    DELETE: deleteMethodDoc
  }
};
export {
  DELETE,
  GET,
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=%5Bid%5D.js.map
