import "server-only";
import { getRegisteredEntities } from "./queries";
class EntityRegistry {
  entities = /* @__PURE__ */ new Map();
  initialized = false;
  /**
   * Register a new entity configuration
   */
  register(config) {
    const validation = this.validateConfiguration(config);
    if (!validation.valid) {
      throw new Error(`Invalid entity configuration for "${config.slug}": ${validation.errors.join(", ")}`);
    }
    this.entities.set(config.slug, config);
    if (validation.warnings.length > 0) {
      console.warn(`Entity "${config.slug}" configuration warnings:`, validation.warnings);
    }
  }
  /**
   * Get entity configuration by slug (updated for new structure)
   */
  get(slug) {
    return this.entities.get(slug);
  }
  /**
   * Get entity configuration by slug
   */
  getBySlug(slug) {
    return this.entities.get(slug);
  }
  /**
   * Get all registered entities
   */
  getAll() {
    return Array.from(this.entities.values());
  }
  /**
   * 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 (!childConfig.permissions) {
        warnings.push("Child entity has no permissions defined");
      }
      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 = []) {
    var _a, _b;
    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 actionConfig = (_b = (_a = entity.permissions) == null ? void 0 : _a.actions) == null ? void 0 : _b.find((a) => a.action === action);
    if (entity.permissions && (!actionConfig || !actionConfig.roles.includes(userRole))) {
      return { allowed: false, reason: "Insufficient role permissions" };
    }
    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
   * CLIENT-SAFE: Skips on client, loads from registries on server
   */
  async initialize() {
    if (this.initialized) return;
    if (typeof window !== "undefined") {
      console.log("[EntityRegistry] Client-side: registry ready for manual registration");
      this.initialized = true;
      return;
    }
    try {
      this.loadFromRegistriesServer();
      this.initialized = true;
      console.log("[EntityRegistry] Server: initialized from build-time registries");
    } catch (error) {
      console.error("[EntityRegistry] Error initializing from registries:", error);
      this.initialized = true;
    }
  }
  /**
   * Server-only registry loading
   * Loads from build-time registries (ENTITY_REGISTRY with static imports)
   * PERFORMANCE: Zero runtime I/O, ~17,255x faster than old dynamic system
   *
   * Note: Uses static import (zero dynamic imports policy)
   */
  loadFromRegistriesServer() {
    const entities = getRegisteredEntities();
    console.log("[EntityRegistry] Loading entities from build-time registry:", entities.length);
    entities.forEach((config, index) => {
      const name = "slug" in config ? config.slug : `entity-${index}`;
      console.log(`[EntityRegistry] Loading entity ${index + 1}/${entities.length}: ${name}`);
      try {
        this.register(config);
        console.log(`[EntityRegistry] \u2705 Successfully registered: ${name}`);
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        console.error(`[EntityRegistry] \u274C Failed to register ${name}:`, errorMessage);
      }
    });
    console.log("[EntityRegistry] Finished loading entities. Total registered:", this.entities.size);
  }
  /**
   * 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
   */
  updateEntity(slug, updates) {
    const existing = this.entities.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.entities.set(slug, updated);
    if (validation.warnings.length > 0) {
      console.warn(`Entity "${slug}" update warnings:`, validation.warnings);
    }
  }
  /**
   * Remove an entity from the registry
   */
  removeEntity(slug) {
    if (!this.entities.has(slug)) {
      throw new Error(`Entity "${slug}" not found`);
    }
    this.entities.delete(slug);
  }
  /**
   * Export all entity configurations
   */
  exportConfigs() {
    return this.getAll();
  }
  /**
   * Import entity configurations
   */
  importConfigs(configs) {
    configs.forEach((config) => this.register(config));
  }
  /**
   * Check if registry is initialized
   */
  isInitialized() {
    return this.initialized;
  }
  /**
   * Reset the registry (alias for clear)
   */
  reset() {
    this.clear();
  }
  /**
   * Clear all registered entities (mainly for testing)
   */
  clear() {
    this.entities.clear();
    this.initialized = false;
  }
}
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["initialized"],
    source: "build-time registries (THEME_REGISTRY + PLUGIN_REGISTRY)"
  };
}
export {
  EntityRegistry,
  ensureInitialized,
  entityRegistry,
  getAllEntityConfigs,
  getEnabledEntities,
  getEntityConfig,
  getEntityLimits,
  getRegistryStats,
  registerEntity
};
