import { getComponent } from "./registry.js";
const instanceStore = new WeakMap();
const config = {
    attributePrefix: "data-ss",
    autoInitEnabled: true,
    observerEnabled: true,
    debug: true,
};
let observer = null;
function parseConfig(element, componentName, defaults = {}) {
    const result = { ...defaults };
    const prefix = `${config.attributePrefix}-${componentName}-`;
    const jsonAttr = `${config.attributePrefix}-${componentName}-config`;
    const jsonConfig = element.getAttribute(jsonAttr);
    if (jsonConfig) {
        try {
            Object.assign(result, JSON.parse(jsonConfig));
        }
        catch (e) {
            console.warn(`[Stylescape] Invalid JSON config for ${componentName}:`, e);
        }
    }
    Array.from(element.attributes).forEach((attr) => {
        if (attr.name.startsWith(prefix) && attr.name !== jsonAttr) {
            const key = attr.name
                .slice(prefix.length)
                .replace(/-([a-z])/g, (_, c) => c.toUpperCase());
            let value = attr.value;
            if (value === "true")
                value = true;
            else if (value === "false")
                value = false;
            else if (!isNaN(Number(value)) && value !== "")
                value = Number(value);
            result[key] = value;
        }
    });
    return result;
}
function initComponent(element, componentName) {
    const entry = getComponent(componentName);
    if (!entry) {
        if (config.debug) {
            console.warn(`[Stylescape] Unknown component: ${componentName}`);
        }
        return null;
    }
    let instances = instanceStore.get(element);
    if (instances?.has(componentName)) {
        if (config.debug) {
            console.log(`[Stylescape] Component "${componentName}" already initialized on element`);
        }
        return instances.get(componentName);
    }
    const componentConfig = parseConfig(element, componentName, entry.defaults);
    try {
        const instance = entry.handler(element, componentConfig);
        if (!instances) {
            instances = new Map();
            instanceStore.set(element, instances);
        }
        instances.set(componentName, instance);
        element.setAttribute(`${config.attributePrefix}-${componentName}-initialized`, "true");
        if (config.debug) {
            console.log(`[Stylescape] Initialized "${componentName}" on`, element);
        }
        return instance;
    }
    catch (e) {
        console.error(`[Stylescape] Error initializing "${componentName}":`, e);
        return null;
    }
}
function initElement(element) {
    const ssAttr = element.getAttribute(config.attributePrefix);
    console.log(`[Stylescape] Processing element:`, {
        element: element.tagName,
        id: element.id,
        dataSs: ssAttr,
    });
    if (!ssAttr)
        return;
    if (element.hasAttribute(`${config.attributePrefix}-manual`)) {
        console.log(`[Stylescape] Skipping manual element:`, element);
        return;
    }
    const componentNames = ssAttr.trim().split(/\s+/);
    console.log(`[Stylescape] Initializing components:`, componentNames);
    componentNames.forEach((name) => {
        if (name) {
            initComponent(element, name.toLowerCase());
        }
    });
}
export function init(root = document.body) {
    console.log("[Stylescape] Auto-init starting...", {
        root: root.tagName,
        autoInitEnabled: config.autoInitEnabled,
    });
    if (!config.autoInitEnabled) {
        if (config.debug) {
            console.log("[Stylescape] Auto-init disabled, skipping");
        }
        return;
    }
    const selector = `[${config.attributePrefix}]`;
    const elements = root.querySelectorAll(selector);
    console.log(`[Stylescape] Found ${elements.length} elements with ${selector}`);
    if (root instanceof HTMLElement &&
        root.hasAttribute(config.attributePrefix)) {
        initElement(root);
    }
    elements.forEach((element) => initElement(element));
    console.log(`[Stylescape] Auto-init complete. Initialized ${elements.length} elements`);
}
export function getInstance(element, componentName) {
    const instances = instanceStore.get(element);
    if (!instances)
        return null;
    if (componentName) {
        return instances.get(componentName.toLowerCase()) || null;
    }
    const values = instances.values();
    const first = values.next();
    return first.done ? null : first.value;
}
export function getAllInstances(element) {
    return instanceStore.get(element) || null;
}
export function reinit(element, componentName) {
    destroy(element, componentName);
    if (componentName) {
        initComponent(element, componentName);
    }
    else {
        initElement(element);
    }
}
export function destroy(element, componentName) {
    const instances = instanceStore.get(element);
    if (!instances)
        return;
    const destroyInstance = (name, instance) => {
        if (instance &&
            typeof instance.destroy ===
                "function") {
            try {
                instance.destroy();
            }
            catch (e) {
                console.warn(`[Stylescape] Error destroying "${name}":`, e);
            }
        }
        instances.delete(name);
        element.removeAttribute(`${config.attributePrefix}-${name}-initialized`);
        if (config.debug) {
            console.log(`[Stylescape] Destroyed "${name}" on`, element);
        }
    };
    if (componentName) {
        const instance = instances.get(componentName.toLowerCase());
        if (instance) {
            destroyInstance(componentName.toLowerCase(), instance);
        }
    }
    else {
        instances.forEach((instance, name) => destroyInstance(name, instance));
        instanceStore.delete(element);
    }
}
export function observe(root = document.body) {
    if (!config.observerEnabled)
        return;
    if (observer) {
        observer.disconnect();
    }
    observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node instanceof HTMLElement) {
                    if (node.hasAttribute(config.attributePrefix)) {
                        initElement(node);
                    }
                    const descendants = node.querySelectorAll(`[${config.attributePrefix}]`);
                    descendants.forEach((el) => initElement(el));
                }
            });
            mutation.removedNodes.forEach((node) => {
                if (node instanceof HTMLElement) {
                    if (instanceStore.has(node)) {
                        destroy(node);
                    }
                    const descendants = node.querySelectorAll(`[${config.attributePrefix}]`);
                    descendants.forEach((el) => {
                        if (instanceStore.has(el)) {
                            destroy(el);
                        }
                    });
                }
            });
        });
    });
    observer.observe(root, {
        childList: true,
        subtree: true,
    });
    if (config.debug) {
        console.log("[Stylescape] Observer started");
    }
}
export function stopObserving() {
    if (observer) {
        observer.disconnect();
        observer = null;
        if (config.debug) {
            console.log("[Stylescape] Observer stopped");
        }
    }
}
export function setAutoInit(enabled) {
    config.autoInitEnabled = enabled;
}
export function setObserver(enabled) {
    config.observerEnabled = enabled;
    if (!enabled && observer) {
        stopObserving();
    }
}
export function setDebug(enabled) {
    config.debug = enabled;
}
export function setAttributePrefix(prefix) {
    config.attributePrefix = prefix;
}
export function autoStart() {
    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", () => {
            init();
            observe();
        });
    }
    else {
        init();
        observe();
    }
}
//# sourceMappingURL=autoInit.js.map