class PuterDialog extends (globalThis.HTMLElement || Object) { // It will fall back to only extending Object in environments without a DOM
    /**
     * Detects if the current page is loaded using the file:// protocol.
     * @returns {boolean} True if using file:// protocol, false otherwise.
     */
    isUsingFileProtocol = ()=>{
        return window.location.protocol === 'file:';
    }
    
    
    constructor(resolve, reject) {
        super();
        this.reject = reject;
        this.resolve = resolve;
        this.popupLaunched = false; // Track if popup was successfully launched

        /**
         * Detects if there's a recent user activation that would allow popup opening
         * @returns {boolean} True if user activation is available, false otherwise.
         */
        this.hasUserActivation = () => {
            // Modern browsers support navigator.userActivation
            if (navigator.userActivation) {
                return navigator.userActivation.hasBeenActive && navigator.userActivation.isActive;
            }
            
            // Fallback: try to detect user activation by attempting to open a popup
            // This is a bit hacky but works as a fallback
            try {
                const testPopup = window.open('', '_blank', 'width=1,height=1,left=-1000,top=-1000');
                if (testPopup) {
                    testPopup.close();
                    return true;
                }
                return false;
            } catch (e) {
                return false;
            }
        }

        /**
         * Launches the authentication popup window
         * @returns {Window|null} The popup window reference or null if failed
         */
        this.launchPopup = () => {
            try {
                let w = 600;
                let h = 400;
                let title = 'Puter';
                var left = (screen.width/2)-(w/2);
                var top = (screen.height/2)-(h/2);
                const popup = window.open(
                    puter.defaultGUIOrigin + '/?embedded_in_popup=true&request_auth=true' + (window.crossOriginIsolated ? '&cross_origin_isolated=true' : ''), 
                    title, 
                    'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left
                );
                return popup;
            } catch (e) {
                console.error('Failed to open popup:', e);
                return null;
            }
        }

        this.attachShadow({ mode: 'open' });

        let h;
        // Dialog
        h = `
        <style>
        dialog{
            background: transparent; 
            border: none; 
            box-shadow: none; 
            outline: none;
        }
        .puter-dialog-content {
            border: 1px solid #e8e8e8;
            border-radius: 8px;
            padding: 20px;
            background: white;
            box-shadow: 0 0 9px 1px rgb(0 0 0 / 21%);
            padding: 80px 20px;
            -webkit-font-smoothing: antialiased;
            color: #575762;
            position: relative;
            background-image: url('data:image/webp;base64,[encoded data, 9336 characters]');
            background-repeat: no-repeat;
            background-position: center center;
            background-size: 100% 100%;
            background-color: #fff;
        }
        
        dialog * {
            max-width: 500px;
            font-family: "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif;
        }
        
        dialog p.about{
            text-align: center;
            font-size: 17px;
            padding: 10px 30px;
            font-weight: 400;
            -webkit-font-smoothing: antialiased;
            color: #404048;
            box-sizing: border-box;
        }
        
        dialog .buttons{
            display: flex;
            justify-content: center;
            align-items: center;
            flex-wrap: wrap;
            margin-top: 20px;
            text-align: center;
            margin-bottom: 20px;
        }
        
        .launch-auth-popup-footnote{
            font-size: 11px;
            color: #666;
            margin-top: 10px;
            /* footer at the bottom */
            position: absolute;
            left: 0;
            right: 0;
            bottom: 10px;
            text-align: center;
            margin: 0 10px;
        }
        
        dialog .close-btn{
            position: absolute;
            right: 15px;
            top: 10px;
            font-size: 17px;
            color: #8a8a8a;
            cursor: pointer;
        }
        
        dialog .close-btn:hover{
            color: #000;
        }
        
        /* ------------------------------------
        Button
        ------------------------------------*/
        
        dialog .button {
            color: #666666;
            background-color: #eeeeee;
            border-color: #eeeeee;
            font-size: 14px;
            text-decoration: none;
            text-align: center;
            line-height: 40px;
            height: 35px;
            padding: 0 30px;
            margin: 0;
            display: inline-block;
            appearance: none;
            cursor: pointer;
            border: none;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            border-color: #b9b9b9;
            border-style: solid;
            border-width: 1px;
            line-height: 35px;
            background: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#e1e1e1));
            background: linear-gradient(#f6f6f6, #e1e1e1);
            -webkit-box-shadow: inset 0px 1px 0px rgb(255 255 255 / 30%), 0 1px 2px rgb(0 0 0 / 15%);
            box-shadow: inset 0px 1px 0px rgb(255 255 255 / 30%), 0 1px 2px rgb(0 0 0 / 15%);
            border-radius: 4px;
            outline: none;
            -webkit-font-smoothing: antialiased;
        }
        
        dialog .button:focus-visible {
            border-color: rgb(118 118 118);
        }
        
        dialog .button:active, dialog .button.active, dialog .button.is-active, dialog .button.has-open-contextmenu {
            text-decoration: none;
            background-color: #eeeeee;
            border-color: #cfcfcf;
            color: #a9a9a9;
            -webkit-transition-duration: 0s;
            transition-duration: 0s;
            -webkit-box-shadow: inset 0 1px 3px rgb(0 0 0 / 20%);
            box-shadow: inset 0px 2px 3px rgb(0 0 0 / 36%), 0px 1px 0px white;
        }
        
        dialog .button.disabled, dialog .button.is-disabled, dialog .button:disabled {
            top: 0 !important;
            background: #EEE !important;
            border: 1px solid #DDD !important;
            text-shadow: 0 1px 1px white !important;
            color: #CCC !important;
            cursor: default !important;
            appearance: none !important;
            pointer-events: none;
        }
        
        dialog .button-action.disabled, dialog .button-action.is-disabled, dialog .button-action:disabled {
            background: #55a975 !important;
            border: 1px solid #60ab7d !important;
            text-shadow: none !important;
            color: #CCC !important;
        }
        
        dialog .button-primary.disabled, dialog .button-primary.is-disabled, dialog .button-primary:disabled {
            background: #8fc2e7 !important;
            border: 1px solid #98adbd !important;
            text-shadow: none !important;
            color: #f5f5f5 !important;
        }
        
        dialog .button-block {
            width: 100%;
        }
        
        dialog .button-primary {
            border-color: #088ef0;
            background: -webkit-gradient(linear, left top, left bottom, from(#34a5f8), to(#088ef0));
            background: linear-gradient(#34a5f8, #088ef0);
            color: white;
        }
        
        dialog .button-danger {
            border-color: #f00808;
            background: -webkit-gradient(linear, left top, left bottom, from(#f83434), to(#f00808));
            background: linear-gradient(#f83434, #f00808);
            color: white;
        }
        
        dialog .button-primary:active, dialog .button-primary.active, dialog .button-primary.is-active, dialog .button-primary-flat:active, dialog .button-primary-flat.active, dialog .button-primary-flat.is-active {
            background-color: #2798eb;
            border-color: #2798eb;
            color: #bedef5;
        }
        
        dialog .button-action {
            border-color: #08bf4e;
            background: -webkit-gradient(linear, left top, left bottom, from(#29d55d), to(#1ccd60));
            background: linear-gradient(#29d55d, #1ccd60);
            color: white;
        }
        
        dialog .button-action:active, dialog .button-action.active, dialog .button-action.is-active, dialog .button-action-flat:active, dialog .button-action-flat.active, dialog .button-action-flat.is-active {
            background-color: #27eb41;
            border-color: #27eb41;
            color: #bef5ca;
        }
        
        dialog .button-giant {
            font-size: 28px;
            height: 70px;
            line-height: 70px;
            padding: 0 70px;
        }
        
        dialog .button-jumbo {
            font-size: 24px;
            height: 60px;
            line-height: 60px;
            padding: 0 60px;
        }
        
        dialog .button-large {
            font-size: 20px;
            height: 50px;
            line-height: 50px;
            padding: 0 50px;
        }
        
        dialog .button-normal {
            font-size: 16px;
            height: 40px;
            line-height: 38px;
            padding: 0 40px;
        }
        
        dialog .button-small {
            height: 30px;
            line-height: 29px;
            padding: 0 30px;
        }
        
        dialog .button-tiny {
            font-size: 9.6px;
            height: 24px;
            line-height: 24px;
            padding: 0 24px;
        }
        
        #launch-auth-popup{
            margin-left: 10px; 
            width: 200px; 
            font-weight: 500; 
            font-size: 15px;
        }
        dialog .button-auth{
            margin-bottom: 10px;
        }
        dialog a, dialog a:visited{
            color: rgb(0 69 238);
            text-decoration: none;
        }
        dialog a:hover{
            text-decoration: underline;
        }
        
        @media (max-width:480px)  { 
            .puter-dialog-content{
                padding: 50px 20px;
            }
            dialog .buttons{
                flex-direction: column-reverse;
            }
            dialog p.about{
                padding: 10px 0;
            }
            dialog .button-auth{
                width: 100% !important;
                margin:0 !important;
                margin-bottom: 10px !important;
            }
        }
        .error-container h1 {
            color: #e74c3c;
            font-size: 20px;
            text-align: center;
        }

        .puter-dialog-content a:focus{
            outline: none;
        }
        </style>`;
        // Error message for unsupported protocol
        if(window.location.protocol === 'file:'){
            h += `<dialog>
                    <div class="puter-dialog-content" style="padding: 20px 40px; background:white !important; font-size: 15px;">
                        <span class="close-btn">&#x2715</span>
                        <div class="error-container">
                            <h1>Puter.js Error: Unsupported Protocol</h1>
                            <p>It looks like you've opened this file directly in your browser (using the <code style="font-family: monospace;">file:///</code> protocol) which is not supported by Puter.js for security reasons.</p>
                            <p>To view this content properly, you need to serve it through a web server. Here are some options:</p>
                            <ul>
                                <li>Use a local development server (e.g., Python's built-in server or Node.js http-server)</li>
                                <li>Upload the files to a web hosting service</li>
                                <li>Use a local server application like XAMPP or MAMP</li>
                            </ul>
                            <p class="help-text">If you're not familiar with these options, consider reaching out to your development team or IT support for assistance.</p>
                        </div>
                        <p style="margin-top: 30px; border-top: 1px solid #eee; padding-top: 10px; text-align: center; font-size:13px;">
                            <a href="https://docs.puter.com" target="_blank">Docs</a><span style="margin:10px; color: #CCC;">|</span>
                            <a href="https://github.com/heyPuter/puter/" target="_blank">Github</a><span style="margin:10px; color: #CCC;">|</span>
                            <a href="https://discord.com/invite/PQcx7Teh8u" target="_blank">Discord</a>
                        </p>
                    </div>
                </dialog>`;
        }else{
            h += `<dialog>
                <div class="puter-dialog-content">
                    <span class="close-btn">&#x2715</span>
                    <a href="https://puter.com" target="_blank" style="border:none; outline:none; display: block; width: 70px; height: 70px; margin: 0 auto; border-radius: 4px;"><img style="display: block; width: 70px; height: 70px; margin: 0 auto; border-radius: 4px;" src="data:image/png;base64,[encoded data, 13820 characters]"/></a>
                    <p class="about">This website uses Puter to bring you safe, secure, and private AI and Cloud features.</p>
                    <div class="buttons">
                        <button class="button button-auth" id="launch-auth-popup-cancel">Cancel</button>
                        <button class="button button-primary button-auth" id="launch-auth-popup" style="margin-left:10px;">Continue</button>
                    </div>
                    <p style="text-align: center; margin-top: -15px; font-size: 14px;">Powered by <a href="https://developer.puter.com/?utm_source=sdk-splash" target="_blank">Puter</a></p>
                    <p class="launch-auth-popup-footnote">By clicking 'Continue' you agree to Puter's <a href="https://puter.com/terms" target="_blank">Terms of Service</a> and <a href="https://puter.com/privacy" target="_blank">Privacy Policy</a>.</p>
                </div>
            </dialog>`;
        }


        this.shadowRoot.innerHTML = h;

        // Event listener for the 'message' event
        this.messageListener = async (event) => {
            if (event.data.msg === 'puter.token') {
                this.close();
                // Set the authToken property
                puter.setAuthToken(event.data.token);
                // update appID
                puter.setAppID(event.data.app_uid);
                // Remove the event listener to avoid memory leaks
                window.removeEventListener('message', this.messageListener);

                puter.puterAuthState.authGranted = true;
                // Resolve the promise
                this.resolve();

                // Call onAuth callback
                if(puter.onAuth && typeof puter.onAuth === 'function'){
                    puter.getUser().then((user) => {
                        puter.onAuth(user)
                    });
                }

                puter.puterAuthState.isPromptOpen = false;
                // Resolve or reject any waiting promises.
                if (puter.puterAuthState.resolver) {
                    if (puter.puterAuthState.authGranted) {
                        puter.puterAuthState.resolver.resolve();
                    } else {
                        puter.puterAuthState.resolver.reject();
                    }
                    puter.puterAuthState.resolver = null;
                };
            }
        };

    }

    // Optional: Handle dialog cancellation as rejection
    cancelListener = () => {
        this.close();
        window.removeEventListener('message', this.messageListener);
        puter.puterAuthState.authGranted = false;
        puter.puterAuthState.isPromptOpen = false;
    
        // Reject the promise with an error message indicating user cancellation.
        // This ensures that the calling code's catch block will be triggered.
        this.reject(new Error('User cancelled the authentication'));
    
        // If there's a resolver set, use it to reject the waiting promise as well.
        if (puter.puterAuthState.resolver) {
            puter.puterAuthState.resolver.reject(new Error('User cancelled the authentication'));
            puter.puterAuthState.resolver = null;
        }
    };

    connectedCallback() {
        // Add event listener to the button
        this.shadowRoot.querySelector('#launch-auth-popup')?.addEventListener('click', ()=>{
            let w = 600;
            let h = 400;
            let title = 'Puter';
            var left = (screen.width/2)-(w/2);
            var top = (screen.height/2)-(h/2);
            window.open(puter.defaultGUIOrigin + '/?embedded_in_popup=true&request_auth=true' + (window.crossOriginIsolated ? '&cross_origin_isolated=true' : ''), 
            title, 
            'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
        })

        // Add the event listener to the window object
        window.addEventListener('message', this.messageListener);    

        // Add event listeners for cancel and close buttons
        this.shadowRoot.querySelector('#launch-auth-popup-cancel')?.addEventListener('click', this.cancelListener);
        this.shadowRoot.querySelector('.close-btn')?.addEventListener('click',this.cancelListener);
    }

    open() {
        if(this.hasUserActivation()){
            let w = 600;
            let h = 400;
            let title = 'Puter';
            var left = (screen.width/2)-(w/2);
            var top = (screen.height/2)-(h/2);
            window.open(puter.defaultGUIOrigin + '/?embedded_in_popup=true&request_auth=true' + (window.crossOriginIsolated ? '&cross_origin_isolated=true' : ''), 
            title, 
            'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
        }
        else{
            this.shadowRoot.querySelector('dialog').showModal();
        }
    }

    close() {
        this.shadowRoot.querySelector('dialog').close();
    }
}
if (PuterDialog.__proto__  === globalThis.HTMLElement)
    customElements.define('puter-dialog', PuterDialog);

export default PuterDialog;
