import { TestRegistry } from './registry.js';
import { Logger } from '../utils/logger.js';
/**
 * Resolves logical selector keys into physical DOM selectors.
 * Purely Database-Driven (MongoDB).
 */
export class SelectorResolver {
    static registry = {};
    static isInitialized = false;
    /**
     * Loads all selector sets from the database.
     */
    static async init() {
        try {
            const registry = await TestRegistry.getInstance();
            const sets = await registry.listSelectors();
            const dbRegistry = {};
            for (const set of sets) {
                const namespace = set.name.toLowerCase();
                for (const [key, selector] of Object.entries(set.mappings)) {
                    dbRegistry[`${namespace}.${key.toLowerCase()}`] = selector;
                }
            }
            // Merge: In-memory selectors take precedence
            this.registry = { ...dbRegistry, ...this.registry };
            this.isInitialized = true;
            Logger.log(`[SelectorResolver] DB Initialized with ${Object.keys(this.registry).length} selectors (case-insensitive).`);
        }
        catch (err) {
            Logger.error('Failed to initialize SelectorResolver from DB', err);
        }
    }
    /**
     * Resolves a key to its primary DOM selector.
     */
    static resolve(key) {
        const selectors = this.resolveMany(key);
        return selectors[0] || key;
    }
    /**
     * Resolves a key to all possible DOM selectors (for self-healing).
     */
    static resolveMany(key) {
        if (!this.isInitialized) {
            Logger.warn(`SelectorResolver called before DB initialization: ${key}`);
        }
        const lowerKey = key.toLowerCase();
        const value = this.registry[lowerKey];
        if (!value) {
            // Handle raw selectors
            const isRawSelector = key.startsWith('#') || key.startsWith('.') || key.startsWith('[') ||
                key.startsWith('/') || key.startsWith('//') || key.startsWith('xpath=') || key.startsWith('(') ||
                key.includes('#') || key.includes('.') || key.includes('[') || key.includes(' > ');
            if (!isRawSelector && key.includes('.') && !key.startsWith('.') && !key.startsWith('#') && !key.includes(' ')) {
                Logger.warn(`SelectorKey "${key}" not found in registry (queried as ${lowerKey}).`);
            }
            return [this.normalize(key)];
        }
        const selectors = Array.isArray(value) ? value : [value];
        return selectors.map(s => this.normalize(s));
    }
    static normalize(selector) {
        if (selector.startsWith('/') || selector.startsWith('(')) {
            if (!selector.startsWith('xpath=')) {
                return `xpath=${selector}`;
            }
        }
        return selector;
    }
    /**
     * REVERSE LOOKUP: Finds the logical key for a given raw selector.
     */
    static findKeyForSelector(selector) {
        for (const [key, val] of Object.entries(this.registry)) {
            if (Array.isArray(val)) {
                if (val.includes(selector))
                    return key;
            }
            else {
                if (val === selector)
                    return key;
            }
        }
        return null;
    }
    /**
     * Returns all unique namespaces currently in the registry.
     */
    static getNamespaces() {
        const namespaces = new Set();
        for (const key of Object.keys(this.registry)) {
            if (key.includes('.')) {
                namespaces.add(key.split('.')[0]);
            }
        }
        return Array.from(namespaces);
    }
    /**
     * MANUALLY SEEDS/UPDATES the registry for a specific namespace.
     * Useful for immediate local execution after recording.
     */
    static updateRegistry(namespace, mappings) {
        const lowerNamespace = namespace.toLowerCase();
        for (const [key, selector] of Object.entries(mappings)) {
            this.registry[`${lowerNamespace}.${key.toLowerCase()}`] = selector;
        }
        this.isInitialized = true;
    }
}
