import "server-only";
import {
  getEntityBySlug,
  getRegisteredEntities,
  addEntityToRegistry,
  removeEntityFromRegistry,
  clearEntityRegistry,
  isRegistryInitialized
} from "./queries.js";
class EntityRegistry {
  /**
   * Register a new entity configuration
   * Adds to the singleton in queries.ts
   */
  register(config) {
    const validation = this.validateConfiguration(config);
    if (!validation.valid) {
      throw new Error(`Invalid entity configuration for "${config.slug}": ${validation.errors.join(", ")}`);
    }
    const entry = {
      name: config.slug,
      config,
      parent: null,
      children: config.childEntities ? Object.keys(config.childEntities) : [],
      depth: 0,
      tableName: config.tableName || config.slug,
      routePrefix: config.slug
    };
    addEntityToRegistry(entry);
    if (validation.warnings.length > 0) {
      console.warn(`Entity "${config.slug}" configuration warnings:`, validation.warnings);
    }
  }
  /**
   * Get entity configuration by slug
   * Delegates to singleton in queries.ts
   */
  get(slug) {
    return getEntityBySlug(slug);
  }
  /**
   * Get entity configuration by slug (alias for get)
   */
  getBySlug(slug) {
    return getEntityBySlug(slug);
  }
  /**
   * Get all registered entities
   * Delegates to singleton in queries.ts
   */
  getAll() {
    const entities = getRegisteredEntities();
    return entities.filter((e) => "slug" in e && "enabled" in e);
  }
  /**
   * Get only enabled entities
   */
  getEnabled() {
    return this.getAll().filter((entity) => entity.enabled);
  }
  /**
   * Get entities that have a specific feature enabled
   */
  getByFeature(feature) {
    return this.getEnabled().filter((entity) => entity.ui.features[feature] === true);
  }
  /**
   * Get effective limits for user (returns unlimited for now since plans are not enforced)
   */
  getEffectiveLimits(entityName, planType, userFlags = []) {
    const entity = this.get(entityName);
    if (!entity) throw new Error(`Entity "${entityName}" not found`);
    const flagFeatures = [];
    return {
      maxRecords: "unlimited",
      features: flagFeatures
    };
  }
  /**
   * Get child entities configuration for a parent entity
   */
  getChildEntities(parentEntityName) {
    const entity = this.get(parentEntityName);
    return entity == null ? void 0 : entity.childEntities;
  }
  /**
   * Get specific child entity configuration
   */
  getChildConfig(parentEntityName, childName) {
    const childEntities = this.getChildEntities(parentEntityName);
    return childEntities == null ? void 0 : childEntities[childName];
  }
  /**
   * Check if entity has child entities
   */
  hasChildEntities(entityName) {
    const entity = this.get(entityName);
    return !!((entity == null ? void 0 : entity.childEntities) && Object.keys(entity.childEntities).length > 0);
  }
  /**
   * Get child entities for API inclusion based on requested children
   */
  getChildrenForAPI(parentEntityName, includedChildren) {
    const childEntities = this.getChildEntities(parentEntityName);
    if (!childEntities) return [];
    if (!includedChildren || includedChildren.includes("all")) {
      return Object.values(childEntities);
    }
    return includedChildren.map((childName) => childEntities[childName]).filter((child) => !!child);
  }
  /**
   * Validate entity configuration
   */
  validateConfiguration(config) {
    var _a, _b, _c, _d, _e, _f;
    const errors = [];
    const warnings = [];
    const isChildEntity = !("enabled" in config);
    if (isChildEntity) {
      const childConfig = config;
      if (!Array.isArray(childConfig.fields)) {
        errors.push("Child entity must have fields array");
      }
      return { valid: errors.length === 0, errors, warnings };
    }
    const entityConfig = config;
    if (!((_a = entityConfig.slug) == null ? void 0 : _a.trim())) errors.push("Entity slug is required");
    if (!((_c = (_b = entityConfig.names) == null ? void 0 : _b.singular) == null ? void 0 : _c.trim())) errors.push("Entity singular name is required");
    if (!((_e = (_d = entityConfig.names) == null ? void 0 : _d.plural) == null ? void 0 : _e.trim())) errors.push("Entity plural name is required");
    if (!entityConfig.icon) errors.push("Icon is required");
    if (typeof entityConfig.enabled !== "boolean") {
      errors.push("enabled must be a boolean");
    }
    if (entityConfig.childEntities) {
      for (const [childName, childConfig] of Object.entries(entityConfig.childEntities)) {
        if (!((_f = childConfig.table) == null ? void 0 : _f.trim())) {
          errors.push(`Child entity "${childName}" must have a table name`);
        }
        if (!Array.isArray(childConfig.fields)) {
          errors.push(`Child entity "${childName}" must have fields array`);
        }
      }
    }
    return { valid: errors.length === 0, errors, warnings };
  }
  /**
   * Get detailed access result for user and entity (excluding plan validation)
   */
  getAccessResult(entityName, action, userRole, planType, userFlags = []) {
    const entity = this.get(entityName);
    if (!entity) {
      return { allowed: false, reason: "Entity not found" };
    }
    if (!entity.enabled) {
      return { allowed: false, reason: "Entity is disabled" };
    }
    const limits = this.getEffectiveLimits(entityName, planType, userFlags);
    const features = limits.features || [];
    return {
      allowed: true,
      limits,
      features
    };
  }
  /**
   * Check if user is at or near entity limits
   */
  checkLimits(entityName, planType, currentUsage, userFlags = []) {
    const limits = this.getEffectiveLimits(entityName, planType, userFlags);
    const warnings = [];
    const errors = [];
    if (limits.maxRecords !== "unlimited") {
      const recordLimit = limits.maxRecords;
      const usage = currentUsage.currentRecords / recordLimit;
      if (currentUsage.currentRecords >= recordLimit) {
        errors.push(`Record limit exceeded: ${currentUsage.currentRecords}/${recordLimit}`);
      } else if (usage >= 0.8) {
        warnings.push(`Approaching record limit: ${currentUsage.currentRecords}/${recordLimit}`);
      }
    }
    if (limits.maxStorage && limits.maxStorage !== "unlimited" && currentUsage.storageUsed) {
      const storageLimit = limits.maxStorage;
      const usage = currentUsage.storageUsed / storageLimit;
      if (currentUsage.storageUsed >= storageLimit) {
        errors.push(`Storage limit exceeded: ${currentUsage.storageUsed}MB/${storageLimit}MB`);
      } else if (usage >= 0.8) {
        warnings.push(`Approaching storage limit: ${currentUsage.storageUsed}MB/${storageLimit}MB`);
      }
    }
    if (limits.maxApiCalls && limits.maxApiCalls !== "unlimited" && currentUsage.apiCalls) {
      const apiLimit = limits.maxApiCalls;
      const usage = currentUsage.apiCalls / apiLimit;
      if (currentUsage.apiCalls >= apiLimit) {
        errors.push(`API call limit exceeded: ${currentUsage.apiCalls}/${apiLimit}`);
      } else if (usage >= 0.8) {
        warnings.push(`Approaching API limit: ${currentUsage.apiCalls}/${apiLimit}`);
      }
    }
    return {
      withinLimits: errors.length === 0,
      warnings,
      errors
    };
  }
  /**
   * Initialize registry
   *
   * ARCHITECTURE: This is now a NO-OP for backwards compatibility.
   * The singleton in queries.ts is populated by:
   * - Server: The layout imports registry and calls setEntityRegistry()
   * - Client: DashboardShell calls setServerEntities() during hydration
   *
   * The EntityRegistry class is a facade - it doesn't need initialization.
   */
  async initialize() {
    const count = this.getAll().length;
    if (count > 0) {
      console.log(`[EntityRegistry] Already initialized with ${count} entities from singleton`);
    } else {
      console.log("[EntityRegistry] Singleton empty - will be populated by layout import");
    }
  }
  /**
   * Get registry statistics
   */
  getStats() {
    const all = this.getAll();
    const enabled = this.getEnabled();
    return {
      totalEntities: all.length,
      enabledEntities: enabled.length,
      entitiesWithChildren: enabled.filter((e) => this.hasChildEntities(e.slug)).length,
      entitiesWithExternalAPI: enabled.filter((e) => e.access.api).length
    };
  }
  /**
   * Update an existing entity configuration
   * Delegates to singleton in queries.ts
   */
  updateEntity(slug, updates) {
    const existing = this.get(slug);
    if (!existing) {
      throw new Error(`Entity "${slug}" not found`);
    }
    const updated = { ...existing, ...updates };
    const validation = this.validateConfiguration(updated);
    if (!validation.valid) {
      throw new Error(`Invalid entity update for "${slug}": ${validation.errors.join(", ")}`);
    }
    this.register(updated);
    if (validation.warnings.length > 0) {
      console.warn(`Entity "${slug}" update warnings:`, validation.warnings);
    }
  }
  /**
   * Remove an entity from the registry
   * Delegates to singleton in queries.ts
   */
  removeEntity(slug) {
    if (!removeEntityFromRegistry(slug)) {
      throw new Error(`Entity "${slug}" not found`);
    }
  }
  /**
   * Export all entity configurations
   */
  exportConfigs() {
    return this.getAll();
  }
  /**
   * Import entity configurations
   */
  importConfigs(configs) {
    configs.forEach((config) => this.register(config));
  }
  /**
   * Check if registry is initialized
   * Delegates to singleton in queries.ts
   */
  isInitialized() {
    return isRegistryInitialized();
  }
  /**
   * Reset the registry (alias for clear)
   */
  reset() {
    this.clear();
  }
  /**
   * Clear all registered entities (mainly for testing)
   * Delegates to singleton in queries.ts
   */
  clear() {
    clearEntityRegistry();
  }
}
const entityRegistry = new EntityRegistry();
function registerEntity(config) {
  entityRegistry.register(config);
}
function getEntityConfig(name) {
  return entityRegistry.get(name);
}
function getEnabledEntities() {
  return entityRegistry.getEnabled();
}
function getEntityLimits(entityName, planType, userFlags = []) {
  return entityRegistry.getEffectiveLimits(entityName, planType, userFlags);
}
async function ensureInitialized() {
  await entityRegistry.initialize();
}
function getAllEntityConfigs() {
  return entityRegistry.getAll();
}
function getRegistryStats() {
  return {
    totalEntities: entityRegistry.getAll().length,
    enabledEntities: entityRegistry.getEnabled().length,
    initialized: entityRegistry.isInitialized(),
    source: "singleton (queries.ts)"
  };
}
export {
  EntityRegistry,
  ensureInitialized,
  entityRegistry,
  getAllEntityConfigs,
  getEnabledEntities,
  getEntityConfig,
  getEntityLimits,
  getRegistryStats,
  registerEntity
};
