/**
 * DreamStack Embed SDK — ~3KB standalone
 * Enables embedding DreamStack apps in any website.
 *
 * Usage:
 *   <script src="dreamstack-embed.js"></script>
 *   <ds-stream src="https://yourapp.com"></ds-stream>
 *
 * Or via JS API:
 *   DreamStack.connect('https://yourapp.com', '#container');
 */
(function (root, factory) {
    if (typeof module !== 'undefined' && module.exports) module.exports = factory();
    else root.DreamStack = factory();
})(typeof globalThis !== 'undefined' ? globalThis : this, function () {
    'use strict';

    // ── Iframe Embed ──
    function embed(src, container, options) {
        var opts = options || {};
        var el = typeof container === 'string' ? document.querySelector(container) : container;
        if (!el) throw new Error('[DreamStack] Container not found: ' + container);

        var iframe = document.createElement('iframe');
        iframe.src = src;
        iframe.style.border = 'none';
        iframe.style.width = opts.width || '100%';
        iframe.style.height = opts.height || '400px';
        iframe.style.borderRadius = opts.borderRadius || '12px';
        iframe.style.overflow = 'hidden';
        iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
        iframe.setAttribute('loading', 'lazy');

        if (opts.className) iframe.className = opts.className;
        el.appendChild(iframe);

        return {
            iframe: iframe,
            destroy: function () { el.removeChild(iframe); },
            resize: function (w, h) {
                iframe.style.width = typeof w === 'number' ? w + 'px' : w;
                iframe.style.height = typeof h === 'number' ? h + 'px' : h;
            }
        };
    }

    // ── Signal Bridge (bidirectional) ──
    function connect(src, container, options) {
        var handle = embed(src, container, options);
        var listeners = {};

        // Listen for messages from the DreamStack app
        window.addEventListener('message', function (e) {
            if (e.source !== handle.iframe.contentWindow) return;
            var data = e.data;
            if (data && data.type === 'ds:signal') {
                var name = data.name;
                if (listeners[name]) {
                    listeners[name].forEach(function (fn) { fn(data.value); });
                }
                if (listeners['*']) {
                    listeners['*'].forEach(function (fn) { fn(name, data.value); });
                }
            }
        });

        return {
            iframe: handle.iframe,
            destroy: handle.destroy,
            resize: handle.resize,

            // Send a signal value to the DreamStack app
            send: function (name, value) {
                handle.iframe.contentWindow.postMessage(
                    { type: 'ds:signal', name: name, value: value }, '*'
                );
            },

            // Listen for signal changes from the DreamStack app
            on: function (name, fn) {
                if (!listeners[name]) listeners[name] = [];
                listeners[name].push(fn);
                return function () {
                    listeners[name] = listeners[name].filter(function (f) { return f !== fn; });
                };
            }
        };
    }

    // ── Web Component: <ds-stream> ──
    if (typeof customElements !== 'undefined') {
        customElements.define('ds-stream', class extends HTMLElement {
            constructor() {
                super();
                this._handle = null;
            }

            connectedCallback() {
                var src = this.getAttribute('src');
                if (!src) return;

                var shadow = this.attachShadow({ mode: 'open' });
                var wrapper = document.createElement('div');
                wrapper.style.width = '100%';
                wrapper.style.height = this.getAttribute('height') || '400px';
                shadow.appendChild(wrapper);

                this._handle = embed(src, wrapper, {
                    width: '100%',
                    height: '100%',
                    borderRadius: this.getAttribute('radius') || '12px'
                });
            }

            disconnectedCallback() {
                if (this._handle) this._handle.destroy();
            }

            static get observedAttributes() { return ['src', 'height']; }
            attributeChangedCallback(name, old, val) {
                if (name === 'src' && this._handle) {
                    this._handle.iframe.src = val;
                } else if (name === 'height' && this._handle) {
                    this._handle.resize('100%', val);
                }
            }
        });
    }

    return {
        embed: embed,
        connect: connect,
        version: '0.1.0'
    };
});
