export default () => ({
    // Toggled while window.nostr.signEvent is awaiting the wallet so the
    // button disables itself, the loading overlay renders, and downstream
    // wire:poll consumers can pause if needed. Stays true through the
    // backend round-trip — the auth-button component reloads the page on
    // success, so resetting the flag here would just flicker the overlay
    // away while navigation is already underway.
    nostrLoginInProgress: false,

    /**
     * Resolve the active NIP-42 login challenge issued by the auth-button
     * Volt component. Falls back to the Livewire $wire proxy and then to a
     * server-side re-issue so the user does not have to reload if the
     * rendered snapshot drifted out of sync with the session (e.g. a tab
     * left open past the challenge TTL).
     */
    async resolveChallenge() {
        const fromDataset = this.$root?.dataset?.nostrChallenge;
        if (typeof fromDataset === 'string' && fromDataset !== '') {
            return fromDataset;
        }

        const livewireComponent = this.$el.closest('[wire\\:id]')?.__livewire;
        const fromWire = livewireComponent?.$wire?.nostrChallenge;
        if (typeof fromWire === 'string' && fromWire !== '') {
            return fromWire;
        }

        if (livewireComponent?.$wire?.requestNostrChallenge) {
            try {
                const refreshed = await livewireComponent.$wire.requestNostrChallenge();
                if (typeof refreshed === 'string' && refreshed !== '') {
                    return refreshed;
                }
            } catch (error) {
                console.error('requestNostrChallenge failed:', error);
            }
        }

        return null;
    },

    async openNostrLogin() {
        this.nostrLoginInProgress = true;

        try {
            if (!window.nostr || typeof window.nostr.signEvent !== 'function') {
                this.showAuthError('Keine Nostr-Erweiterung gefunden. Bitte installiere einen Nostr-Signer (z.B. nos2x, Alby).');
                this.nostrLoginInProgress = false;
                return;
            }

            const challenge = await this.resolveChallenge();
            if (!challenge) {
                this.showAuthError('Login-Challenge fehlt. Bitte lade die Seite neu und versuche es erneut.');
                this.nostrLoginInProgress = false;
                return;
            }

            const pubkey = await window.nostr.getPublicKey();

            const event = {
                kind: 22242,
                created_at: Math.floor(Date.now() / 1000),
                tags: [['challenge', challenge]],
                content: '',
            };

            let signedEvent;
            try {
                signedEvent = await window.nostr.signEvent(event);
            } catch (error) {
                console.error('Nostr signEvent failed:', error);
                this.showAuthError('Signatur abgebrochen oder fehlgeschlagen. Bitte versuche es erneut.');
                this.nostrLoginInProgress = false;
                return;
            }

            // Some Nostr extensions return objects wrapped in extension-specific
            // proxies (e.g. cloneInto results) that Livewire cannot serialize.
            // Round-trip through JSON to guarantee a plain, cloneable object.
            let plainSignedEvent;
            try {
                plainSignedEvent = JSON.parse(JSON.stringify(signedEvent));
            } catch (error) {
                console.error('Nostr signedEvent serialization failed:', error);
                this.showAuthError('Wallet-Signatur konnte nicht verarbeitet werden. Bitte versuche eine andere Erweiterung.');
                this.nostrLoginInProgress = false;
                return;
            }

            // Pre-fetch the profile so it lands in the Alpine store before the
            // reload completes. Non-critical: failures are logged but ignored.
            try {
                const response = await fetch('/api/nostr/profile/' + pubkey);
                if (response.ok) {
                    const data = await response.json();
                    Alpine.store('nostr', {user: data});
                }
            } catch (error) {
                console.warn('Profile prefetch failed:', error);
            }

            // Leave nostrLoginInProgress = true: the auth-button listener
            // will trigger a full page reload on success.
            this.$dispatch('nostrLoggedIn', {signedEvent: plainSignedEvent});
        } catch (error) {
            console.error('openNostrLogin unexpected error:', error);
            this.showAuthError('Authentifizierung fehlgeschlagen. Bitte versuche es erneut.');
            this.nostrLoginInProgress = false;
        }
    },

    showAuthError(message) {
        if (window.Flux && window.Flux.toast) {
            window.Flux.toast({
                heading: 'Authentifizierung fehlgeschlagen',
                text: message,
                variant: 'danger',
                duration: 8000,
            });
        } else {
            console.error(message);
        }
    },
});
