import { NextResponse } from "next/server";
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 { WorkflowInstance } from "../../../../data/entities.js";
import * as workflowExecutor from "../../../../lib/workflow-executor.js";
import * as transitionHandler from "../../../../lib/transition-handler.js";
import { z } from "zod";
import {
  workflowsTag,
  advanceWorkflowRequestSchema,
  advanceWorkflowResponseSchema,
  workflowErrorSchema
} from "../../../openapi.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("workflows");
const advanceWorkflowSchema = z.object({
  toStepId: z.string().optional(),
  // Optional - will auto-select if not provided
  triggerData: z.record(z.string(), z.any()).optional(),
  // Optional trigger data
  contextUpdates: z.record(z.string(), z.any()).optional()
  // Optional context updates
});
async function POST(request, context) {
  try {
    const container = await createRequestContainer();
    const em = container.resolve("em");
    const auth = await getAuthFromRequest(request);
    if (!auth) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }
    const scope = await resolveOrganizationScopeForRequest({ container, auth, request });
    const tenantId = auth.tenantId;
    const organizationId = scope?.selectedId ?? auth.orgId;
    if (!tenantId || !organizationId) {
      return NextResponse.json(
        { error: "Missing tenant or organization context" },
        { status: 400 }
      );
    }
    const params = await context.params;
    const instanceId = params.id;
    const instance = await em.findOne(WorkflowInstance, {
      id: instanceId,
      tenantId,
      organizationId
    });
    if (!instance) {
      return NextResponse.json(
        { error: "Workflow instance not found" },
        { status: 404 }
      );
    }
    const rbacService = container.resolve("rbacService");
    const hasPermission = await rbacService.userHasAllFeatures(
      auth.sub,
      ["workflows.instances.create"],
      // Using create permission for advancing
      { tenantId, organizationId }
    );
    if (!hasPermission) {
      return NextResponse.json(
        { error: "Insufficient permissions" },
        { status: 403 }
      );
    }
    const body = await request.json().catch(() => ({}));
    const validation = advanceWorkflowSchema.safeParse(body);
    if (!validation.success) {
      return NextResponse.json(
        {
          error: "Validation failed",
          details: validation.error.issues
        },
        { status: 400 }
      );
    }
    const input = validation.data;
    if (instance.status === "COMPLETED") {
      return NextResponse.json(
        { error: "Workflow already completed" },
        { status: 400 }
      );
    }
    if (instance.status === "CANCELLED") {
      return NextResponse.json(
        { error: "Workflow is cancelled" },
        { status: 400 }
      );
    }
    if (instance.status === "FAILED") {
      return NextResponse.json(
        { error: "Workflow has failed. Use retry endpoint to retry." },
        { status: 400 }
      );
    }
    if (input.contextUpdates) {
      await workflowExecutor.updateWorkflowContext(
        em,
        instanceId,
        input.contextUpdates
      );
      await em.flush();
    }
    const evalContext = {
      workflowContext: instance.context,
      userId: auth.sub,
      triggerData: input.triggerData
    };
    const validTransitions = await transitionHandler.findValidTransitions(
      em,
      instance,
      instance.currentStepId,
      evalContext
    );
    const validTransitionsList = validTransitions.filter((t) => t.isValid);
    if (validTransitionsList.length === 0) {
      return NextResponse.json(
        {
          error: "No valid transitions available",
          currentStepId: instance.currentStepId,
          reason: "All transitions blocked by conditions or business rules"
        },
        { status: 400 }
      );
    }
    let selectedTransition;
    if (input.toStepId) {
      const matchingTransition = validTransitionsList.find(
        (t) => t.transition?.toStepId === input.toStepId
      );
      if (!matchingTransition) {
        return NextResponse.json(
          {
            error: `No valid transition to step '${input.toStepId}'`,
            availableTransitions: validTransitionsList.map((t) => ({
              toStepId: t.transition?.toStepId,
              toStepName: t.transition?.toStepName
            }))
          },
          { status: 400 }
        );
      }
      selectedTransition = matchingTransition.transition;
    } else {
      selectedTransition = validTransitionsList[0].transition;
    }
    const execContext = {
      workflowContext: instance.context,
      userId: auth.sub,
      triggerData: input.triggerData
    };
    const transitionResult = await transitionHandler.executeTransition(
      em,
      container,
      instance,
      selectedTransition.fromStepId,
      selectedTransition.toStepId,
      execContext
    );
    if (!transitionResult.success) {
      return NextResponse.json(
        {
          error: "Transition failed",
          reason: transitionResult.error || "Unknown error"
        },
        { status: 400 }
      );
    }
    await em.refresh(instance);
    const executionResult = await workflowExecutor.executeWorkflow(
      em,
      container,
      instanceId,
      {
        userId: auth.sub
      }
    );
    return NextResponse.json(
      {
        data: {
          instance: {
            id: instance.id,
            status: instance.status,
            currentStepId: instance.currentStepId,
            previousStepId: selectedTransition.fromStepId,
            transitionFired: selectedTransition.transitionId,
            context: instance.context
          },
          execution: executionResult
        },
        message: "Workflow advanced successfully"
      },
      { status: 200 }
    );
  } catch (error) {
    logger.error("Error advancing workflow", { err: error });
    if (error instanceof Error) {
      return NextResponse.json(
        {
          error: "Failed to advance workflow",
          message: error.message
        },
        { status: 500 }
      );
    }
    return NextResponse.json(
      { error: "Failed to advance workflow" },
      { status: 500 }
    );
  }
}
const metadata = {
  requireAuth: true,
  requireFeatures: ["workflows.instances.create"]
};
const openApi = {
  tag: workflowsTag,
  summary: "Advance workflow instance",
  methods: {
    POST: {
      summary: "Manually advance workflow to next step",
      description: "Manually advance a workflow instance to the next step. Useful for manual progression, step-by-step testing, user-triggered transitions, and approval flows. Validates transitions and auto-progresses if possible.",
      requestBody: {
        contentType: "application/json",
        schema: advanceWorkflowRequestSchema
      },
      responses: [
        { status: 200, description: "Workflow advanced successfully", schema: advanceWorkflowResponseSchema }
      ],
      errors: [
        { status: 400, description: "Invalid request, no valid transitions, or workflow already completed/cancelled/failed", schema: workflowErrorSchema },
        { status: 401, description: "Unauthorized", schema: workflowErrorSchema },
        { status: 403, description: "Insufficient permissions", schema: workflowErrorSchema },
        { status: 404, description: "Workflow instance not found", schema: workflowErrorSchema },
        { status: 500, description: "Internal server error", schema: workflowErrorSchema }
      ]
    }
  }
};
export {
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
