import { mutateWithRLS, getTransactionClient } from "../db.js";
import { APP_CONFIG_MERGED } from "../config/config-sync.js";
async function scheduleAction(actionType, payload, options) {
  var _a;
  const dedupeConfig = (_a = APP_CONFIG_MERGED.scheduledActions) == null ? void 0 : _a.deduplication;
  const windowSeconds = (dedupeConfig == null ? void 0 : dedupeConfig.windowSeconds) ?? 5;
  const payloadObj = payload;
  const entityId = payloadObj == null ? void 0 : payloadObj.entityId;
  const entityType = payloadObj == null ? void 0 : payloadObj.entityType;
  const shouldDeduplicate = windowSeconds > 0 && entityId && !(options == null ? void 0 : options.recurringInterval);
  const actionId = globalThis.crypto.randomUUID();
  const scheduledAt = (options == null ? void 0 : options.scheduledAt) || /* @__PURE__ */ new Date();
  const teamId = (options == null ? void 0 : options.teamId) || null;
  const recurringInterval = (options == null ? void 0 : options.recurringInterval) || null;
  const lockGroup = (options == null ? void 0 : options.lockGroup) || null;
  const maxRetries = (options == null ? void 0 : options.maxRetries) ?? 3;
  const recurrenceType = (options == null ? void 0 : options.recurrenceType) || null;
  if (shouldDeduplicate) {
    const dedupKey = `${actionType}:${entityId}:${entityType || ""}`;
    const client = await getTransactionClient(null);
    try {
      await client.query(`SELECT pg_advisory_xact_lock(hashtext($1))`, [dedupKey]);
      const existing = await client.query(
        `SELECT id
         FROM "scheduled_actions"
         WHERE "actionType" = $1
           AND status = 'pending'
           AND payload->>'entityId' = $2
           AND payload->>'entityType' = $3
           AND "createdAt" > NOW() - INTERVAL '1 second' * $4
         LIMIT 1`,
        [actionType, entityId, entityType || "", windowSeconds]
      );
      if (existing.length > 0) {
        await client.query(
          `UPDATE "scheduled_actions"
           SET payload = $1, "updatedAt" = NOW()
           WHERE id = $2 AND status = 'pending'`,
          [payload, existing[0].id]
        );
        await client.commit();
        console.log(`[ScheduledActions] Duplicate detected, updated payload: ${existing[0].id}`);
        return existing[0].id;
      }
      await client.query(
        `INSERT INTO "scheduled_actions" (
          id,
          "actionType",
          status,
          payload,
          "teamId",
          "scheduledAt",
          "recurringInterval",
          "lockGroup",
          "maxRetries",
          "recurrenceType"
        ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
        [
          actionId,
          actionType,
          "pending",
          payload,
          teamId,
          scheduledAt.toISOString(),
          recurringInterval,
          lockGroup,
          maxRetries,
          recurrenceType
        ]
      );
      await client.commit();
      console.log(`[ScheduledActions] Scheduled action '${actionType}' with ID: ${actionId}${lockGroup ? ` (lockGroup: ${lockGroup})` : ""}`);
      return actionId;
    } catch (error) {
      await client.rollback();
      throw error;
    }
  }
  await mutateWithRLS(
    `INSERT INTO "scheduled_actions" (
      id,
      "actionType",
      status,
      payload,
      "teamId",
      "scheduledAt",
      "recurringInterval",
      "lockGroup",
      "maxRetries",
      "recurrenceType"
    ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
    [
      actionId,
      actionType,
      "pending",
      payload,
      teamId,
      scheduledAt.toISOString(),
      recurringInterval,
      lockGroup,
      maxRetries,
      recurrenceType
    ],
    null
    // System operation, no RLS context needed
  );
  console.log(`[ScheduledActions] Scheduled action '${actionType}' with ID: ${actionId}${lockGroup ? ` (lockGroup: ${lockGroup})` : ""}`);
  return actionId;
}
async function scheduleRecurringAction(actionType, payload, interval, options) {
  return scheduleAction(actionType, payload, {
    ...options,
    recurringInterval: interval
  });
}
async function cancelScheduledAction(actionId) {
  const result = await mutateWithRLS(
    `UPDATE "scheduled_actions"
     SET status = 'failed',
         "errorMessage" = 'Action cancelled by system',
         "updatedAt" = NOW()
     WHERE id = $1 AND status = 'pending'`,
    [actionId],
    null
  );
  const cancelled = result.rowCount > 0;
  if (cancelled) {
    console.log(`[ScheduledActions] Cancelled action: ${actionId}`);
  } else {
    console.warn(`[ScheduledActions] Could not cancel action ${actionId} (not found or not pending)`);
  }
  return cancelled;
}
export {
  cancelScheduledAction,
  scheduleAction,
  scheduleRecurringAction
};
