import { NextResponse } from "next/server";
import { z } from "zod";
import { runWithCacheTenant } from "@open-mercato/cache";
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { InboxProposal, InboxProposalAction } from "../../../../../../data/entities.js";
import { recalculateProposalStatus } from "../../../../../../lib/executionEngine.js";
import { formatZodErrors } from "../../../../../../lib/validation.js";
import { resolveCache, invalidateCountsCache } from "../../../../../../lib/cache.js";
import {
  resolveRequestContext,
  resolveActionAndProposal,
  handleRouteError,
  isErrorResponse
} from "../../../../../routeHelpers.js";
const metadata = {
  PATCH: { requireAuth: true, requireFeatures: ["inbox_ops.proposals.manage"] }
};
const completeBodySchema = z.object({
  createdEntityId: z.string().uuid(),
  createdEntityType: z.string().trim().min(1).max(100)
});
async function PATCH(req) {
  try {
    const ctx = await resolveRequestContext(req);
    const resolved = await resolveActionAndProposal(new URL(req.url), ctx);
    if (isErrorResponse(resolved)) return resolved;
    const { action, proposal } = resolved;
    if (action.status !== "pending" && action.status !== "failed") {
      return NextResponse.json(
        { error: "Action already processed" },
        { status: 409 }
      );
    }
    let body;
    try {
      body = await req.json();
    } catch {
      return NextResponse.json({ error: "Invalid JSON body" }, { status: 400 });
    }
    const parsed = completeBodySchema.safeParse(body);
    if (!parsed.success) {
      return NextResponse.json({ error: `Invalid body: ${formatZodErrors(parsed.error)}` }, { status: 400 });
    }
    const em = ctx.em.fork();
    const freshAction = await findOneWithDecryption(
      em,
      InboxProposalAction,
      { id: action.id, deletedAt: null },
      void 0,
      ctx.scope
    );
    if (!freshAction) {
      return NextResponse.json({ error: "Action not found" }, { status: 404 });
    }
    freshAction.status = "executed";
    freshAction.executedAt = /* @__PURE__ */ new Date();
    freshAction.executedByUserId = ctx.userId;
    freshAction.createdEntityId = parsed.data.createdEntityId;
    freshAction.createdEntityType = parsed.data.createdEntityType;
    freshAction.executionError = null;
    await em.flush();
    await recalculateProposalStatus(em, proposal.id, ctx.scope);
    const freshProposal = await findOneWithDecryption(
      em,
      InboxProposal,
      { id: proposal.id, deletedAt: null },
      void 0,
      ctx.scope
    );
    const cache = resolveCache(ctx.container);
    await runWithCacheTenant(ctx.tenantId, () => invalidateCountsCache(cache, ctx.tenantId));
    return NextResponse.json({
      ok: true,
      action: {
        id: freshAction.id,
        status: freshAction.status,
        createdEntityId: freshAction.createdEntityId,
        createdEntityType: freshAction.createdEntityType,
        executedAt: freshAction.executedAt
      },
      proposal: freshProposal ? {
        id: freshProposal.id,
        status: freshProposal.status
      } : null
    });
  } catch (err) {
    return handleRouteError(err, "complete action");
  }
}
const openApi = {
  tag: "InboxOps",
  summary: "Complete action externally",
  methods: {
    PATCH: {
      summary: "Mark an action as completed with an externally-created entity",
      description: "Used when an action is fulfilled through the normal sales form instead of the execution engine. Updates the action status without running the execution engine.",
      responses: [
        { status: 200, description: "Action marked as completed" },
        { status: 400, description: "Invalid body" },
        { status: 404, description: "Action not found" },
        { status: 409, description: "Action already processed" }
      ]
    }
  }
};
export {
  PATCH,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
