const
	PageList = require( '../mobile.startup/PageList' ),
	WatchstarPageList = require( '../mobile.startup/watchstar/WatchstarPageList' ),
	ScrollEndEventEmitter = require( './ScrollEndEventEmitter' ),
	util = require( '../mobile.startup/util' ),
	WatchListGateway = require( './WatchListGateway' );

/**
 * An extension of the WatchstarPageList which preloads pages as all being
 * watched.
 *
 * @uses ScrollEndEventEmitter
 *
 * @fires watched
 * @fires watch
 * @private
 */
class WatchList extends WatchstarPageList {
	/**
	 * @param {Object} params Configuration options
	 * @param {OO.EventEmitter} params.eventBus Object used to listen for scroll:throttled events
	 */
	constructor( params ) {
		super( util.extend(
			{},
			{
				isBorderBox: false
			},
			params
		) );
	}

	initialize( options ) {
		// Set up infinite scroll helper and listen to events
		this.scrollEndEventEmitter = new ScrollEndEventEmitter( options.eventBus );
		this.scrollEndEventEmitter.on( ScrollEndEventEmitter.EVENT_SCROLL_END,
			() => this._loadPages() );

		let lastTitle;
		if ( options.el ) {
			lastTitle = this.getLastTitle( options.el );
		}
		this.gateway = new WatchListGateway( options.api, lastTitle );
		super.initialize( options );
	}

	preRender() {
		// The DOM will be modified. Prevent any false scroll end events from
		// being emitted.
		this.scrollEndEventEmitter.disable();
		this.scrollEndEventEmitter.setElement( this.$el );
	}

	/**
	 * Also sets a watch uploads funnel.
	 *
	 * @inheritdoc
	 */
	postRender() {
		// Skip a level from WatchstarPageList directly to PageList.
		PageList.prototype.postRender.apply( this );

		const $items = this.queryUnitializedItems();

		// WatchList requests list of watched pages. The list contains only
		// watched pages so it's safe to transform the title map to a status map
		// with each entry marked watched (true).
		const statuses = Object.keys( this.parsePagesFromItems( $items ) )
			.reduce( ( arr, title ) => {
				arr[ title ] = true;
				return arr;
			}, {} );
		this.renderItems( $items, statuses );

		// The list has been extended. Re-enable scroll end events.
		this.scrollEndEventEmitter.enable();
	}

	/**
	 * Loads pages from the api and triggers render.
	 * Infinite scroll is re-enabled in postRender.
	 *
	 */
	_loadPages() {
		this.gateway.loadWatchlist().then( ( pages ) => {
			pages.forEach( ( page ) => {
				this.appendPage( page );
			} );
			this.render();
		} );
	}

	/**
	 * Appends a list item
	 *
	 * @param {Page} page
	 */
	appendPage( page ) {
		// wikidata descriptions should not show in this view.
		const templateOptions = util.extend( {}, page, {
			wikidataDescription: undefined
		} );
		this.$el.append( this.templatePartials.item.render( templateOptions ) );
	}

	/**
	 * Get the last title from the rendered HTML.
	 * Used for initializing the API
	 *
	 * @param {jQuery.Object} $el Dom element of the list
	 * @return {string}
	 */
	getLastTitle( $el ) {
		return $el.find( 'li' ).last().attr( 'title' );
	}
}

module.exports = WatchList;