import { invalidateCrudCache } from "@open-mercato/shared/lib/crud/cache";
import { runWithCacheTenant } from "@open-mercato/cache";
import { createModuleQueue } from "@open-mercato/queue";
import "../commands/deals.js";
import { createLogger } from "@open-mercato/shared/lib/logger";
const logger = createLogger("customers");
const CUSTOMERS_DEALS_BULK_UPDATE_STAGE_QUEUE = "customers-deals-bulk-update-stage";
const CUSTOMERS_DEALS_BULK_UPDATE_OWNER_QUEUE = "customers-deals-bulk-update-owner";
const queues = /* @__PURE__ */ new Map();
function getCustomersQueue(queueName) {
  const existing = queues.get(queueName);
  if (existing) return existing;
  const concurrency = Math.max(
    1,
    Number.parseInt(process.env.CUSTOMERS_QUEUE_CONCURRENCY ?? "3", 10) || 3
  );
  const created = createModuleQueue(queueName, { concurrency });
  queues.set(queueName, created);
  return created;
}
class BulkDealsPreflightError extends Error {
  constructor(code, message) {
    super(message);
    this.name = "BulkDealsPreflightError";
    this.code = code;
  }
}
async function verifyPipelineStageExists(em, stageId, scope) {
  const rows = await em.getConnection().execute(
    `SELECT id FROM customer_pipeline_stages
       WHERE id = ?
         AND tenant_id = ?
         AND organization_id = ?
       LIMIT 1`,
    [stageId, scope.tenantId, scope.organizationId]
  );
  if (rows.length === 0) {
    throw new BulkDealsPreflightError(
      "pipeline_stage_not_found",
      `Pipeline stage ${stageId} does not exist in this tenant`
    );
  }
}
const BULK_CACHE_ALIASES = ["customers.deals"];
function buildCommandContext(scope, container) {
  return {
    container,
    auth: null,
    organizationScope: {
      selectedId: scope.organizationId,
      filterIds: [scope.organizationId],
      allowedIds: [scope.organizationId],
      tenantId: scope.tenantId
    },
    selectedOrganizationId: scope.organizationId,
    organizationIds: [scope.organizationId]
  };
}
async function runBulkDealUpdate(params) {
  const { container, progressJobId, ids, scope, cacheSource, buildBody, logTag } = params;
  const commandBus = container.resolve("commandBus");
  const progressService = container.resolve("progressService");
  const progressContext = {
    tenantId: scope.tenantId,
    organizationId: scope.organizationId,
    userId: scope.userId
  };
  await progressService.startJob(progressJobId, progressContext);
  await progressService.updateProgress(
    progressJobId,
    { totalCount: ids.length, processedCount: 0 },
    progressContext
  );
  const commandContext = buildCommandContext(scope, container);
  const updatedIds = /* @__PURE__ */ new Set();
  const failedItems = [];
  let affectedCount = 0;
  for (const [index, id] of ids.entries()) {
    try {
      await commandBus.execute(
        "customers.deals.update",
        {
          input: buildBody(id),
          ctx: commandContext,
          skipCacheInvalidation: true
        }
      );
      affectedCount += 1;
      updatedIds.add(id);
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      failedItems.push({ id, message });
      logger.warn("Failed to update deal", { component: logTag, jobId: progressJobId, id, err: error });
    }
    await progressService.updateProgress(
      progressJobId,
      { totalCount: ids.length, processedCount: index + 1 },
      progressContext
    );
  }
  await runWithCacheTenant(scope.tenantId, async () => {
    for (const id of updatedIds) {
      await invalidateCrudCache(
        container,
        "customers.deal",
        { id, organizationId: scope.organizationId, tenantId: scope.tenantId },
        scope.tenantId,
        cacheSource,
        BULK_CACHE_ALIASES
      );
    }
  });
  const summary = {
    affectedCount,
    failedCount: failedItems.length,
    failedItems
  };
  await progressService.completeJob(progressJobId, { resultSummary: summary }, progressContext);
  return summary;
}
async function bulkUpdateDealStageWithProgress(params) {
  const em = params.container.resolve("em");
  await verifyPipelineStageExists(em, params.pipelineStageId, params.scope);
  return runBulkDealUpdate({
    container: params.container,
    progressJobId: params.progressJobId,
    ids: params.ids,
    scope: params.scope,
    cacheSource: "bulk-update-stage:customers.deals",
    logTag: "customers.deals.bulk-update-stage",
    buildBody: (id) => ({ id, pipelineStageId: params.pipelineStageId })
  });
}
async function bulkUpdateDealOwnerWithProgress(params) {
  return runBulkDealUpdate({
    container: params.container,
    progressJobId: params.progressJobId,
    ids: params.ids,
    scope: params.scope,
    cacheSource: "bulk-update-owner:customers.deals",
    logTag: "customers.deals.bulk-update-owner",
    buildBody: (id) => ({ id, ownerUserId: params.ownerUserId })
  });
}
export {
  BulkDealsPreflightError,
  CUSTOMERS_DEALS_BULK_UPDATE_OWNER_QUEUE,
  CUSTOMERS_DEALS_BULK_UPDATE_STAGE_QUEUE,
  bulkUpdateDealOwnerWithProgress,
  bulkUpdateDealStageWithProgress,
  getCustomersQueue
};
//# sourceMappingURL=bulkDeals.js.map
