/**
 * controllers/ShortenLinkCard.js
 *
 * @file Provides controller for ShortenLinkCard component
 *
 * @author Jessie Hildebrandt
 */

/* -------------------------------------------------------------------------- */
/* Local module imports */

import { ShortenedLinksPanel } from '../interfaces/ShortenedLinksPanel.js';

import { cancelRequestsToURL, delayedInterruptableRequest, formDataFromObject, sleep } from '../utils/utils.js';

/* -------------------------------------------------------------------------- */
/* Controller implementation */

/**
 * Controller for ShortenLinkCard component
 */
const ShortenLinkCard = {

    /* ---------------------------------- */
    /* Enums */

    FIELD_STATE: {
        EMPTY: '',
        VALIDATING: 'validating',
        VALID: 'valid',
        INVALID: 'invalid'
    },

    /* ---------------------------------- */
    /* init */

    /**
     * Initialize the controller
     */
    init()
    {

        ShortenLinkCard.linkName = '';
        ShortenLinkCard.linkDest = '';

        ShortenLinkCard.linkNameState = '';
        ShortenLinkCard.linkDestState = '';

        ShortenLinkCard.isWaiting = false;

    },

    /* ---------------------------------- */
    /* reset */

    /**
     * Reset the controller
     */
    reset()
    {
        ShortenLinkCard.init();
    },

    /* ---------------------------------- */
    /* refresh */

    /**
     * Trigger a full refresh and redraw of the component
     */
    refresh()
    {
        ShortenLinkCard.updateLinkName( ShortenLinkCard.linkName );
        ShortenLinkCard.updateLinkDest( ShortenLinkCard.linkDest );
    },

    /* ---------------------------------- */
    /* updateLinkName */

    /**
     * Update the link name stored in the controller
     *
     * @param {string} value - The value to update the link name to
     */
    async updateLinkName( value )
    {

        // If the field was cleared, clear its state
        if ( ( ShortenLinkCard.linkName = value ) === '' )
        {
            cancelRequestsToURL( '/shorten/api/validate/link_id' );
            ShortenLinkCard.linkNameState = ShortenLinkCard.FIELD_STATE.EMPTY;
            return;
        }

        // Attempt to validate the new link name value
        try
        {
            ShortenLinkCard.linkNameState = ShortenLinkCard.FIELD_STATE.VALIDATING;
            await delayedInterruptableRequest( '/shorten/api/validate/link_id', `?data=${ value }`, 200 );
            ShortenLinkCard.linkNameState = ShortenLinkCard.FIELD_STATE.VALID;
        }
        catch
        {
            ShortenLinkCard.linkNameState = ShortenLinkCard.FIELD_STATE.INVALID;
        }

    },

    /* ---------------------------------- */
    /* updateLinkDest */

    /**
     * Update the link destination stored in the controller
     *
     * @param {string} value - The value to update the link destination to
     */
    async updateLinkDest( value )
    {

        // If the field was cleared, clear its state
        if ( ( ShortenLinkCard.linkDest = value ) === '' )
        {
            cancelRequestsToURL( '/shorten/api/validate/link_dest' );
            ShortenLinkCard.linkDestState = ShortenLinkCard.FIELD_STATE.EMPTY;
            return;
        }

        // Attempt to validate the new link destination
        try
        {
            ShortenLinkCard.linkDestState = ShortenLinkCard.FIELD_STATE.VALIDATING;
            await delayedInterruptableRequest( '/shorten/api/validate/link_dest', `?data=${ value }`, 200 );
            ShortenLinkCard.linkDestState = ShortenLinkCard.FIELD_STATE.VALID;
        }
        catch
        {
            ShortenLinkCard.linkDestState = ShortenLinkCard.FIELD_STATE.INVALID;
        }

    },

    /* ---------------------------------- */
    /* canShorten */

    /**
     * Return true if the current state of the "Shorten a link" card is valid for submission
     *
     * @returns {boolean} Whether or not the current card state is valid for submission
     */
    canShorten()
    {
        if ( ShortenLinkCard.linkDestState === ShortenLinkCard.FIELD_STATE.VALID
             && !ShortenLinkCard.linkNameState !== ShortenLinkCard.FIELD_STATE.VALIDATING
             && !ShortenLinkCard.linkNameState !== ShortenLinkCard.FIELD_STATE_INVALID )
        {
            return true;
        }
        return false;
    },

    /* ---------------------------------- */
    /* tryShorten */

    /**
     * Attempt to create a new shortened link entry
     */
    async tryShorten()
    {

        // Signal to the component that activity is occurring
        ShortenLinkCard.isWaiting = true;
        m.redraw();

        // Prevent the input fields from disabling and then re-enabling too quickly
        await sleep( 150 );

        // Attempt to create a new shortened link entry by submitting a request to the API
        try
        {
            const response = await m.request( {
                method: 'POST',
                url: `/shorten/api/links/${ ShortenLinkCard.linkName }`,
                body: formDataFromObject( { link_dest: ShortenLinkCard.linkDest } ),
                background: true
            } );
        }
        catch
        {}

        // Clear the input fields
        ShortenLinkCard.updateLinkName( '' );
        ShortenLinkCard.updateLinkDest( '' );

        // Refresh the "Shortened links" UI component's list of links
        ShortenedLinksPanel.refresh();

        // We're done our work
        ShortenLinkCard.isWaiting = false;
        m.redraw();

    }

};

/* -------------------------------------------------------------------------- */
/* Export */

export { ShortenLinkCard };
