/** @typedef { import('types/HovercardResponse.js').HovercardResponse} HovercardResponse */

export default function hovercard(){
    return {

        /**
         * @type {boolean}
         */
        start: false,

        /**
         * @type {HovercardResponse}
         */
        data: null,

        /**
         * @type {boolean}
         */
        loading: false,

        /**
         * @type {any}
         */
        error: false,

        /**
         * @type {HTMLElement|null}
         */
        anchorEl: null,

        /**
         * @type {number}
         */
        x: 0,

        /**
         * @type {number}
         */
        y: 0,

        /**
         *
         * @param {HTMLElement} anchorEl
         * @param {string} fetchUrl
         * @return {Promise<void>}
         */
        async open(anchorEl, fetchUrl){

            if( this.start && this.anchorEl === anchorEl ){
                // this.close();
                return;
            }

            this.start = true;
            this.anchorEl = anchorEl;
            this.data = null;
            this.loading = true;
            this.error = false;
            this.updatePosition(anchorEl);

            try {
                const RESPONSE = await fetch(fetchUrl);
                if( !RESPONSE.ok )
                    throw new Error(RESPONSE.status);

                let json = await RESPONSE.json();
                if( !json.user )
                    throw new Error(RESPONSE.status);

                this.data = json.user;

                Alpine.nextTick(() => {
                    const card = document.querySelector('.hovercard');
                    if (card) window.refreshIcons(card);
                });

            } catch( error ){
                this.error = true;
            } finally {
                this.loading = false;
            }
        },

        /**
         * Update Hovercard position
         * @param {HTMLElement} anchorEl
         */
        updatePosition(anchorEl){
            const RECT = anchorEl.getBoundingClientRect();
            const SCROLL_X = window.scrollX;
            const SCROLL_Y = window.scrollY;

            let x = RECT.left + SCROLL_X;
            let y = RECT.bottom + SCROLL_Y + 8;

            const WIDTH = 280;
            if( x + WIDTH > window.innerWidth ){
                x = window.innerWidth - WIDTH - 16;
            }

            this.x = x;
            this.y = y;
        },

        /**
         * Close the hovercard.
         */
        close(){
            this.start = false;
            this.data = null;
            this.anchorEl = null;
            this.error = false;
        }
    }
}
