(function () {
  const config = window.foodordConfirmStatus;
  window.foodordConfirmStatus = undefined;
  if ( ! config ) {
    return;
  }

  const container = document.getElementById( 'foodord-confirm-status' );
  const pendingText = ( config.messages && config.messages.pending ) ? config.messages.pending : 'Awaiting restaurant confirmation…';
  if ( container ) {
    container.textContent = pendingText;
  }

  const confirmedTemplate = ( config.messages && config.messages.confirmed ) ? config.messages.confirmed : 'Restaurant confirmation: %s';
  let lastSignature = null;
  let interval = parseInt( config.interval, 10 );
  if ( ! isFinite( interval ) || interval < 2000 ) {
    interval = 15000;
  }

  function dispatchStatusEvent( status, label, info, progress ) {
    try {
      const detail = {
        status: status,
        info: info || {},
        label: label,
        progress: progress || ( info && info.progress ? info.progress : null )
      };

      [ 'foodord:confirm-status', 'foodord-theme:confirm-status' ].forEach( function ( eventName ) {
        try {
          window.dispatchEvent( new CustomEvent( eventName, { detail: detail } ) );
        } catch ( innerError ) {
          void innerError;
        }
      } );
    } catch ( error ) {
      void error;
    }
  }

  function applyPending( info ) {
    if ( container ) {
      container.textContent = pendingText;
    }
    const stageSignature = info && info.progress && info.progress.stage ? info.progress.stage : '';
    lastSignature = 'pending:' + stageSignature;
    dispatchStatusEvent( info && info.status ? info.status : 'pending', pendingText, info, info && info.progress ? info.progress : null );
  }

  function applyConfirmed( info ) {
    let label = '';
    if ( info && typeof info === 'object' ) {
      if ( info.confirmed_display ) {
        label = info.confirmed_display;
      } else if ( info.confirmed_slot_local ) {
        label = info.confirmed_slot_local;
      } else if ( info.confirmed_minutes ) {
        label = info.confirmed_minutes + ' min';
      } else if ( info.confirmed_at_local ) {
        label = info.confirmed_at_local;
      } else if ( info.confirmed_slot ) {
        const slotDate = new Date( info.confirmed_slot );
        if ( ! Number.isNaN( slotDate.getTime() ) ) {
          label = slotDate.toLocaleTimeString( [], { hour: '2-digit', minute: '2-digit' } );
        }
      } else if ( info.confirmed_at ) {
        label = info.confirmed_at;
      }
    }

    let signature;
    try {
      signature = JSON.stringify( {
        label: label,
        display: info && info.confirmed_display ? info.confirmed_display : '',
        slot: info && info.confirmed_slot ? info.confirmed_slot : '',
        slotLocal: info && info.confirmed_slot_local ? info.confirmed_slot_local : '',
        minutes: info && typeof info.confirmed_minutes !== 'undefined' ? info.confirmed_minutes : null,
        at: info && info.confirmed_at ? info.confirmed_at : '',
        atLocal: info && info.confirmed_at_local ? info.confirmed_at_local : '',
        stage: info && info.progress && info.progress.stage ? info.progress.stage : ''
      } );
    } catch {
      signature = null;
    }

    if ( signature && signature === lastSignature ) {
      return;
    }

    lastSignature = signature || null;
    if ( container ) {
      const text = confirmedTemplate.replace( '%s', label );
      container.textContent = text;
    }

    dispatchStatusEvent( 'confirmed', label, info, info && info.progress ? info.progress : null );
  }

  function poll() {
    const formBody = new FormData();
    formBody.append( 'action', 'foodord_confirm_status' );
    formBody.append( 'order_key', config.orderKey || '' );
    formBody.append( 'nonce', config.nonce || '' );

    fetch( config.ajaxUrl, {
      method: 'POST',
      credentials: 'same-origin',
      body: formBody
    } )
      .then( function ( response ) {
        return response.json();
      } )
      .then( function ( payload ) {
        if ( ! payload || true !== payload.success ) {
          return;
        }

        const info = payload.data || {};
        if ( info.status === 'confirmed' ) {
          applyConfirmed( info );
        } else {
          applyPending( info );
        }
      } )
      .catch( function () {
        return;
      } );
  }

  poll();
  window.setInterval( function () {
    poll();
  }, interval );
})();
