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 { resolveOrganizationScopeForRequest } from "@open-mercato/core/modules/directory/utils/organizationScope";
import { serializeOperationMetadata } from "@open-mercato/shared/lib/commands/operationMetadata";
import { CrudHttpError, isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
import { parseScopedCommandInput } from "@open-mercato/shared/lib/api/scoped";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { StaffTeamMember } from "../../../data/entities.js";
import {
  staffTeamMemberSelfCreateSchema
} from "../../../data/validators.js";
import {
  resolveUserFeatures,
  runStaffMutationGuardAfterSuccess,
  runStaffMutationGuards
} from "../../guards.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("staff");
const metadata = {
  GET: { requireAuth: true, requireFeatures: ["staff.leave_requests.send"] },
  POST: { requireAuth: true, requireFeatures: ["staff.leave_requests.send"] }
};
async function buildContext(req) {
  const container = await createRequestContainer();
  const auth = await getAuthFromRequest(req);
  const { translate } = await resolveTranslations();
  if (!auth) throw new CrudHttpError(401, { error: translate("staff.errors.unauthorized", "Unauthorized") });
  const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req });
  const ctx = {
    container,
    auth,
    organizationScope: scope,
    selectedOrganizationId: scope?.selectedId ?? auth.orgId ?? null,
    organizationIds: scope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),
    request: req
  };
  return { ctx, translate };
}
const selfMemberResponseSchema = z.object({
  member: z.object({
    id: z.string().uuid(),
    displayName: z.string(),
    userId: z.string().uuid().nullable(),
    teamId: z.string().uuid().nullable(),
    availabilityRuleSetId: z.string().uuid().nullable()
  }).nullable()
});
async function GET(req) {
  try {
    const { ctx } = await buildContext(req);
    const auth = ctx.auth;
    if (!auth?.sub) return NextResponse.json({ member: null });
    const em = ctx.container.resolve("em");
    const member = await findOneWithDecryption(
      em,
      StaffTeamMember,
      { userId: auth.sub, deletedAt: null },
      void 0,
      { tenantId: auth.tenantId ?? null, organizationId: ctx.selectedOrganizationId ?? null }
    );
    if (!member) return NextResponse.json({ member: null });
    return NextResponse.json({
      member: {
        id: member.id,
        displayName: member.displayName,
        userId: member.userId ?? null,
        teamId: member.teamId ?? null,
        availabilityRuleSetId: member.availabilityRuleSetId ?? null
      }
    });
  } catch (err) {
    if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status });
    logger.error("staff.teamMembers.self.load failed", { err });
    return NextResponse.json({ member: null });
  }
}
async function POST(req) {
  try {
    const { ctx, translate } = await buildContext(req);
    const auth = ctx.auth;
    if (!auth?.sub) throw new CrudHttpError(401, { error: translate("staff.errors.unauthorized", "Unauthorized") });
    const body = await req.json().catch(() => ({}));
    const parsed = parseScopedCommandInput(staffTeamMemberSelfCreateSchema, body, ctx, translate);
    const em = ctx.container.resolve("em");
    const existing = await findOneWithDecryption(
      em,
      StaffTeamMember,
      { userId: auth.sub, deletedAt: null },
      void 0,
      { tenantId: auth.tenantId ?? null, organizationId: ctx.selectedOrganizationId ?? null }
    );
    if (existing) {
      throw new CrudHttpError(409, { error: translate("staff.teamMembers.self.exists", "Team member profile already exists.") });
    }
    const tenantId = auth.tenantId ?? "";
    const organizationId = ctx.selectedOrganizationId ?? null;
    const guardResult = await runStaffMutationGuards(
      ctx.container,
      {
        tenantId,
        organizationId,
        userId: auth.sub,
        resourceKind: "staff.team_member",
        resourceId: auth.sub,
        operation: "create",
        requestMethod: req.method,
        requestHeaders: req.headers,
        mutationPayload: parsed
      },
      resolveUserFeatures(auth)
    );
    if (!guardResult.ok) {
      return NextResponse.json(
        guardResult.errorBody ?? { error: "Operation blocked by guard" },
        { status: guardResult.errorStatus ?? 422 }
      );
    }
    const commandBus = ctx.container.resolve("commandBus");
    const selfInput = {
      ...parsed,
      userId: auth.sub,
      teamId: null,
      roleIds: [],
      tags: [],
      availabilityRuleSetId: null,
      isActive: true
    };
    const { result, logEntry } = await commandBus.execute(
      "staff.team-members.create",
      {
        input: selfInput,
        ctx
      }
    );
    if (guardResult.afterSuccessCallbacks.length) {
      await runStaffMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
        tenantId,
        organizationId,
        userId: auth.sub,
        resourceKind: "staff.team_member",
        resourceId: result?.memberId ?? auth.sub,
        operation: "create",
        requestMethod: req.method,
        requestHeaders: req.headers
      });
    }
    const response = NextResponse.json({ id: result?.memberId ?? null }, { status: 201 });
    if (logEntry?.undoToken && logEntry?.id && logEntry?.commandId) {
      response.headers.set(
        "x-om-operation",
        serializeOperationMetadata({
          id: logEntry.id,
          undoToken: logEntry.undoToken,
          commandId: logEntry.commandId,
          actionLabel: logEntry.actionLabel ?? null,
          resourceKind: logEntry.resourceKind ?? "staff.team_member",
          resourceId: logEntry.resourceId ?? result?.memberId ?? null,
          executedAt: logEntry.createdAt instanceof Date ? logEntry.createdAt.toISOString() : void 0
        })
      );
    }
    return response;
  } catch (err) {
    if (isCrudHttpError(err)) {
      return NextResponse.json(err.body, { status: err.status });
    }
    const { translate } = await resolveTranslations();
    logger.error("staff.teamMembers.self.create failed", { err });
    return NextResponse.json({ error: translate("staff.teamMembers.form.errors.create", "Failed to create team member.") }, { status: 400 });
  }
}
const openApi = {
  tag: "Staff",
  summary: "Self team member profile",
  methods: {
    GET: {
      summary: "Get current user team member profile",
      description: "Returns the staff team member linked to the current user, if any.",
      responses: [
        { status: 200, description: "Team member profile", schema: selfMemberResponseSchema },
        { status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) }
      ]
    },
    POST: {
      summary: "Create current user team member profile",
      description: "Creates a team member profile for the signed-in user.",
      requestBody: {
        contentType: "application/json",
        schema: staffTeamMemberSelfCreateSchema
      },
      responses: [
        { status: 201, description: "Team member created", schema: z.object({ id: z.string().uuid().nullable() }) },
        { status: 400, description: "Invalid payload", schema: z.object({ error: z.string() }) },
        { status: 401, description: "Unauthorized", schema: z.object({ error: z.string() }) },
        { status: 409, description: "Already exists", schema: z.object({ error: z.string() }) }
      ]
    }
  }
};
export {
  GET,
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
