var HookPriority = /* @__PURE__ */ ((HookPriority2) => {
  HookPriority2[HookPriority2["HIGHEST"] = 0] = "HIGHEST";
  HookPriority2[HookPriority2["HIGH"] = 10] = "HIGH";
  HookPriority2[HookPriority2["NORMAL"] = 50] = "NORMAL";
  HookPriority2[HookPriority2["LOW"] = 90] = "LOW";
  HookPriority2[HookPriority2["LOWEST"] = 100] = "LOWEST";
  return HookPriority2;
})(HookPriority || {});
class EntityHookManager {
  hooks = /* @__PURE__ */ new Map();
  stats = /* @__PURE__ */ new Map();
  enabled = true;
  /**
   * Register a hook for a specific entity and hook type
   */
  registerHook(entityName, hookType, hook, priority = 50 /* NORMAL */, name) {
    const key = `${entityName}:${hookType}`;
    const existing = this.hooks.get(key) || [];
    existing.push({ hook, priority, name });
    existing.sort((a, b) => a.priority - b.priority);
    this.hooks.set(key, existing);
  }
  /**
   * Register hooks from entity configuration
   */
  registerEntityHooks(config) {
    if (!config.hooks) return;
    const slug = config.slug;
    for (const [hookType, hooks] of Object.entries(config.hooks)) {
      if (Array.isArray(hooks)) {
        hooks.forEach((hook) => {
          const priority = hookType === "onPlanLimitReached" ? 10 /* HIGH */ : 50 /* NORMAL */;
          this.registerHook(slug, hookType, hook, priority);
        });
      }
    }
  }
  /**
   * Execute hooks for a specific entity and hook type
   */
  async executeHooks(entityName, hookType, context) {
    if (!this.enabled) {
      return { continue: true };
    }
    const key = `${entityName}:${hookType}`;
    const hooks = this.hooks.get(key) || [];
    if (hooks.length === 0) {
      return { continue: true };
    }
    const startTime = Date.now();
    let modifiedData = context.data;
    for (const { hook, name } of hooks) {
      try {
        const hookContext = {
          ...context,
          data: modifiedData
          // Pass modified data from previous hooks
        };
        const result = await hook(hookContext);
        if (result && !result.continue) {
          this.updateStats(key, Date.now() - startTime);
          return result;
        }
        if ((result == null ? void 0 : result.data) !== void 0) {
          modifiedData = result.data;
        }
      } catch (error) {
        console.error(`Hook execution failed for ${key}${name ? ` (${name})` : ""}:`, error);
        if (hookType.includes("before") || hookType.includes("validation")) {
          return {
            continue: false,
            error: `Hook execution failed: ${error instanceof Error ? error.message : "Unknown error"}`
          };
        }
        continue;
      }
    }
    this.updateStats(key, Date.now() - startTime);
    return {
      continue: true,
      data: modifiedData
    };
  }
  /**
   * Execute before hooks (can modify data and stop execution)
   */
  async executeBeforeHooks(entityName, operation, context) {
    const hookType = `before${operation.charAt(0).toUpperCase() + operation.slice(1)}`;
    return this.executeHooks(entityName, hookType, context);
  }
  /**
   * Execute after hooks (notifications, cleanup, etc.)
   */
  async executeAfterHooks(entityName, operation, context) {
    const hookType = `after${operation.charAt(0).toUpperCase() + operation.slice(1)}`;
    await this.executeHooks(entityName, hookType, context);
  }
  /**
   * Execute plan limit hooks
   */
  async executePlanLimitHooks(entityName, limitType, context) {
    const hookType = limitType === "reached" ? "onPlanLimitReached" : "onPlanUpgradeRequired";
    return this.executeHooks(entityName, hookType, context);
  }
  /**
   * Execute flag system hooks
   */
  async executeFlagHooks(entityName, flagEvent, context) {
    const hookTypeMap = {
      conflict: "onFlagConflict",
      granted: "onFlagAccessGranted",
      denied: "onFlagAccessDenied"
    };
    return this.executeHooks(entityName, hookTypeMap[flagEvent], context);
  }
  /**
   * Execute child entity hooks
   */
  async executeChildHooks(parentEntityName, childName, hookType, context) {
    const parentResult = await this.executeHooks(parentEntityName, hookType, context);
    if (!parentResult.continue) return parentResult;
    const childKey = `${parentEntityName}.${childName}`;
    return this.executeHooks(childKey, hookType, {
      ...context,
      data: parentResult.data || context.data
    });
  }
  /**
   * Remove hooks for an entity
   */
  removeEntityHooks(entityName) {
    const keysToRemove = Array.from(this.hooks.keys()).filter(
      (key) => key.startsWith(`${entityName}:`)
    );
    keysToRemove.forEach((key) => this.hooks.delete(key));
  }
  /**
   * Remove specific hook
   */
  removeHook(entityName, hookType, hookName) {
    const key = `${entityName}:${hookType}`;
    const hooks = this.hooks.get(key) || [];
    if (hookName) {
      const filtered = hooks.filter((h) => h.name !== hookName);
      this.hooks.set(key, filtered);
    } else {
      this.hooks.delete(key);
    }
  }
  /**
   * Get registered hooks for entity
   */
  getEntityHooks(entityName) {
    const entityHooks = {};
    for (const [key, hooks] of this.hooks.entries()) {
      if (key.startsWith(`${entityName}:`)) {
        const hookType = key.split(":")[1];
        entityHooks[hookType] = hooks;
      }
    }
    return entityHooks;
  }
  /**
   * Update hook execution statistics
   */
  updateStats(key, executionTime) {
    const [entityName, hookType] = key.split(":");
    const statsKey = `${entityName}-${hookType}`;
    const existing = this.stats.get(statsKey);
    if (existing) {
      existing.executionCount++;
      existing.averageExecutionTime = (existing.averageExecutionTime * (existing.executionCount - 1) + executionTime) / existing.executionCount;
      existing.lastExecuted = /* @__PURE__ */ new Date();
    } else {
      this.stats.set(statsKey, {
        entityName,
        hookType,
        executionCount: 1,
        averageExecutionTime: executionTime,
        lastExecuted: /* @__PURE__ */ new Date()
      });
    }
  }
  /**
   * Get hook execution statistics
   */
  getStats() {
    return Array.from(this.stats.values());
  }
  /**
   * Enable/disable hook execution
   */
  setEnabled(enabled) {
    this.enabled = enabled;
  }
  /**
   * Clear all hooks and stats
   */
  clear() {
    this.hooks.clear();
    this.stats.clear();
  }
  /**
   * Get total number of registered hooks
   */
  getHookCount() {
    return Array.from(this.hooks.values()).reduce((total, hooks) => total + hooks.length, 0);
  }
}
const entityHookManager = new EntityHookManager();
function registerHook(entityName, hookType, hook, priority, name) {
  entityHookManager.registerHook(entityName, hookType, hook, priority, name);
}
function executeEntityHooks(entityName, hookType, context) {
  return entityHookManager.executeHooks(entityName, hookType, context);
}
function executeBeforeHooks(entityName, operation, context) {
  return entityHookManager.executeBeforeHooks(entityName, operation, context);
}
function executeAfterHooks(entityName, operation, context) {
  return entityHookManager.executeAfterHooks(entityName, operation, context);
}
const logOperationHook = async (context) => {
  console.log(`[${context.entityName}] ${context.operation} operation by user ${context.user.id}`);
  return { continue: true };
};
const validateRequiredFieldsHook = async (_context) => {
  return { continue: true };
};
const checkPlanLimitsHook = async (context) => {
  if (context.operation === "create") {
    console.log(`Checking plan limits for ${context.entityName}`);
  }
  return { continue: true };
};
const auditTrailHook = async (context) => {
  if (["create", "update", "delete"].includes(context.operation)) {
    console.log(`[AUDIT] ${context.entityName} ${context.operation} by ${context.user.role} user ${context.user.id}`);
  }
  return { continue: true };
};
export {
  EntityHookManager,
  HookPriority,
  auditTrailHook,
  checkPlanLimitsHook,
  entityHookManager,
  executeAfterHooks,
  executeBeforeHooks,
  executeEntityHooks,
  logOperationHook,
  registerHook,
  validateRequiredFieldsHook
};
