import { NextResponse } from "next/server";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
import { getIntegration } from "@open-mercato/shared/modules/integrations/types";
import { runSyncSchema } from "../data/validators.js";
import { startDataSyncRun } from "../lib/start-run.js";
import { getDataSyncAdapter } from "../lib/adapter-registry.js";
import {
  runCrudMutationGuardAfterSuccess,
  validateCrudMutationGuard
} from "@open-mercato/shared/lib/crud/mutation-guard";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("data_sync").child({ component: "run" });
const metadata = {
  POST: { requireAuth: true, requireFeatures: ["data_sync.run"] }
};
const openApi = {
  tags: ["DataSync"],
  summary: "Start a data sync run"
};
async function POST(req) {
  try {
    const auth = await getAuthFromRequest(req);
    if (!auth?.tenantId || !auth.orgId) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }
    const payload = await readJsonSafe(req);
    const parsed = runSyncSchema.safeParse(payload);
    if (!parsed.success) {
      return NextResponse.json({ error: "Invalid payload", details: parsed.error.flatten() }, { status: 422 });
    }
    const container = await createRequestContainer();
    const syncRunService = container.resolve("dataSyncRunService");
    const progressService = container.resolve("progressService");
    const integrationStateService = container.resolve("integrationStateService");
    const scope = {
      organizationId: auth.orgId,
      tenantId: auth.tenantId
    };
    const integration = getIntegration(parsed.data.integrationId);
    if (!integration?.providerKey) {
      return NextResponse.json({ error: "Integration not found" }, { status: 404 });
    }
    const adapter = getDataSyncAdapter(integration.providerKey);
    if (!adapter) {
      return NextResponse.json({ error: "No registered sync adapter for provider" }, { status: 404 });
    }
    if (adapter.runMode === "provider") {
      return NextResponse.json(
        {
          error: "This integration must be started from its provider-specific import flow.",
          settingsPath: `/backend/integrations/${encodeURIComponent(parsed.data.integrationId)}`
        },
        { status: 422 }
      );
    }
    if (!adapter.supportedEntities.includes(parsed.data.entityType)) {
      return NextResponse.json({ error: "Unsupported entity type for this integration" }, { status: 422 });
    }
    const integrationEnabled = await integrationStateService.isEnabled(parsed.data.integrationId, scope);
    if (!integrationEnabled) {
      return NextResponse.json({ error: "Integration is disabled" }, { status: 409 });
    }
    const overlap = await syncRunService.findRunningOverlap(
      parsed.data.integrationId,
      parsed.data.entityType,
      parsed.data.direction,
      scope
    );
    if (overlap) {
      return NextResponse.json({ error: "A sync run is already in progress for this integration and entity direction" }, { status: 409 });
    }
    const guardResult = await validateCrudMutationGuard(container, {
      tenantId: auth.tenantId,
      organizationId: scope.organizationId,
      userId: auth.sub,
      resourceKind: "data_sync.run",
      resourceId: parsed.data.integrationId,
      operation: "custom",
      requestMethod: req.method,
      requestHeaders: req.headers,
      mutationPayload: parsed.data
    });
    if (guardResult && !guardResult.ok) {
      return NextResponse.json(guardResult.body, { status: guardResult.status });
    }
    const cursor = parsed.data.fullSync ? null : await syncRunService.resolveCursor(parsed.data.integrationId, parsed.data.entityType, parsed.data.direction, scope);
    const { run, progressJob } = await startDataSyncRun({
      syncRunService,
      progressService,
      scope: {
        ...scope,
        userId: auth.sub
      },
      input: {
        integrationId: parsed.data.integrationId,
        entityType: parsed.data.entityType,
        direction: parsed.data.direction,
        cursor,
        triggeredBy: parsed.data.triggeredBy ?? auth.sub,
        batchSize: parsed.data.batchSize
      }
    });
    if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
      await runCrudMutationGuardAfterSuccess(container, {
        tenantId: auth.tenantId,
        organizationId: scope.organizationId,
        userId: auth.sub,
        resourceKind: "data_sync.run",
        resourceId: run.id,
        operation: "custom",
        requestMethod: req.method,
        requestHeaders: req.headers,
        metadata: guardResult.metadata ?? null
      });
    }
    return NextResponse.json({ id: run.id, progressJobId: progressJob?.id ?? null }, { status: 201 });
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    const stack = error instanceof Error ? error.stack : void 0;
    logger.error("Unhandled error starting sync run", { message, stack });
    return NextResponse.json(
      { error: "Failed to start data sync run." },
      { status: 500 }
    );
  }
}
export {
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=run.js.map
