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 { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
import { z } from "zod";
import { startDataSyncRun } from "@open-mercato/core/modules/data_sync/lib/start-run";
import { SyncMapping } from "@open-mercato/core/modules/data_sync/data/entities";
import { SyncExcelUpload } from "../../data/entities.js";
import { Attachment } from "../../../attachments/data/entities.js";
import { createCursor } from "../../lib/adapters/customers.js";
import {
  syncExcelImportRequestSchema,
  syncExcelImportResponseSchema
} from "../../data/validators.js";
import { resolveSyncExcelConcreteScope } from "../../lib/scope.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("sync_excel").child({ component: "import" });
const metadata = {
  POST: { requireAuth: true, requireFeatures: ["sync_excel.run"] }
};
const errorSchema = z.object({
  error: z.string()
});
const openApi = {
  tags: ["SyncExcel"],
  summary: "Start a CSV import run for a stored sync_excel upload",
  methods: {
    POST: {
      summary: "Start CSV import",
      responses: [
        { status: 201, description: "Import run started", schema: syncExcelImportResponseSchema },
        { status: 401, description: "Unauthorized", schema: errorSchema },
        { status: 404, description: "Upload not found", schema: errorSchema },
        { status: 409, description: "Import overlap detected", schema: errorSchema },
        { status: 422, description: "Invalid import payload", schema: errorSchema }
      ]
    }
  }
};
async function POST(request) {
  try {
    const auth = await getAuthFromRequest(request);
    if (!auth?.tenantId) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }
    const payload = await readJsonSafe(request);
    const parsedPayload = syncExcelImportRequestSchema.safeParse(payload);
    if (!parsedPayload.success) {
      return NextResponse.json({ error: "Invalid import payload." }, { status: 422 });
    }
    const container = await createRequestContainer();
    const em = container.resolve("em");
    const syncRunService = container.resolve("dataSyncRunService");
    const progressService = container.resolve("progressService");
    const credentialsService = container.resolve("integrationCredentialsService");
    const integrationStateService = container.resolve("integrationStateService");
    const scopeResult = await resolveSyncExcelConcreteScope({ auth, container, request });
    if (!scopeResult.ok) {
      return NextResponse.json({ error: scopeResult.error }, { status: scopeResult.status });
    }
    const { scope } = scopeResult;
    const upload = await findOneWithDecryption(
      em,
      SyncExcelUpload,
      {
        id: parsedPayload.data.uploadId,
        organizationId: scope.organizationId,
        tenantId: scope.tenantId
      },
      void 0,
      scope
    );
    if (!upload) {
      return NextResponse.json({ error: "Upload preview not found." }, { status: 404 });
    }
    const attachment = await findOneWithDecryption(
      em,
      Attachment,
      {
        id: upload.attachmentId,
        organizationId: scope.organizationId,
        tenantId: scope.tenantId
      },
      void 0,
      scope
    );
    if (!attachment) {
      return NextResponse.json({ error: "Upload attachment not found." }, { status: 404 });
    }
    if (upload.entityType !== parsedPayload.data.entityType) {
      return NextResponse.json({ error: "Upload entity type does not match requested import target." }, { status: 422 });
    }
    if (parsedPayload.data.mapping.entityType !== parsedPayload.data.entityType) {
      return NextResponse.json({ error: "Mapping entity type does not match requested import target." }, { status: 422 });
    }
    const overlap = await syncRunService.findRunningOverlap("sync_excel", parsedPayload.data.entityType, "import", scope);
    if (overlap) {
      return NextResponse.json({ error: "A sync_excel import is already in progress for this entity type." }, { status: 409 });
    }
    const existingMapping = await findOneWithDecryption(
      em,
      SyncMapping,
      {
        integrationId: "sync_excel",
        entityType: parsedPayload.data.entityType,
        organizationId: scope.organizationId,
        tenantId: scope.tenantId
      },
      void 0,
      scope
    );
    await em.transactional(async () => {
      if (existingMapping) {
        existingMapping.mapping = parsedPayload.data.mapping;
      } else {
        em.persist(em.create(SyncMapping, {
          integrationId: "sync_excel",
          entityType: parsedPayload.data.entityType,
          mapping: parsedPayload.data.mapping,
          organizationId: scope.organizationId,
          tenantId: scope.tenantId
        }));
      }
      await credentialsService.save("sync_excel", {}, scope);
      await integrationStateService.upsert("sync_excel", { isEnabled: true }, scope);
    });
    const { run, progressJob } = await startDataSyncRun({
      syncRunService,
      progressService,
      scope: {
        ...scope,
        userId: auth.sub
      },
      input: {
        integrationId: "sync_excel",
        entityType: parsedPayload.data.entityType,
        direction: "import",
        cursor: createCursor(upload.id, 0),
        triggeredBy: auth.sub,
        batchSize: parsedPayload.data.batchSize ?? 100,
        progressJob: {
          jobType: "sync_excel:import",
          name: `CSV import \u2014 ${parsedPayload.data.entityType}`,
          description: upload.filename,
          meta: {
            integrationId: "sync_excel",
            uploadId: upload.id,
            hiddenFromTopBar: false
          }
        }
      }
    });
    await em.transactional(async () => {
      upload.syncRunId = run.id;
      upload.status = "importing";
    });
    return NextResponse.json(syncExcelImportResponseSchema.parse({
      runId: run.id,
      progressJobId: progressJob?.id ?? null,
      status: run.status
    }), { 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 import", { message, stack });
    return NextResponse.json(
      { error: "Failed to start sync_excel import." },
      { status: 500 }
    );
  }
}
export {
  POST,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
