/**
 * Single Quiz View.
 *
 * @since 3.16.0
 * @version 5.4.0
 */
define( [
		'Models/Quiz',
		'Views/Popover',
		'Views/PostSearch',
		'Views/QuestionBank',
		'Views/QuestionList',
		'Views/SettingsFields',
		'Views/_Detachable',
		'Views/_Editable',
		'Views/_Subview',
		'Views/_Trashable'
	], function(
		QuizModel,
		Popover,
		PostSearch,
		QuestionBank,
		QuestionList,
		SettingsFields,
		Detachable,
		Editable,
		Subview,
		Trashable
	) {

	return Backbone.View.extend( _.defaults( {

		/**
		 * Current view state.
		 *
		 * @type {String}
		 */
		state: 'default',

		/**
		 * Current Subviews.
		 *
		 * @type {Object}
		 */
		views: {
			settings: {
				class: SettingsFields,
				instance: null,
				state: 'default',
			},
			bank: {
				class: QuestionBank,
				instance: null,
				state: 'default',
			},
			list: {
				class: QuestionList,
				instance: null,
				state: 'default',
			},
		},

		el: '#llms-editor-quiz',

		/**
		 * Events.
		 *
		 * @type {Object}
		 */
		events: _.defaults( {
			'click #llms-existing-quiz': 'add_existing_quiz_click',
			'click #llms-new-quiz': 'add_new_quiz',
			'click #llms-show-question-bank': 'show_tools',
			'click .bulk-toggle': 'bulk_toggle',
			// 'keyup #llms-question-bank-filter': 'filter_question_types',
			// 'search #llms-question-bank-filter': 'filter_question_types',
		}, Detachable.events, Editable.events, Trashable.events ),

		/**
		 * Wrapper Tag name.
		 *
		 * @type {String}
		 */
		tagName: 'div',

		/**
		 * Get the underscore template
		 *
		 * @type {[type]}
		 */
		template: wp.template( 'llms-quiz-template' ),

		/**
		 * Initialization callback func (renders the element on screen).
		 *
		 * @since 3.16.0
		 * @since 3.19.2 Unknown.
		 *
		 * @return {Void}
		 */
		initialize: function( data ) {

			this.lesson = data.lesson;

			// Initialize the model if the quiz is enabled or it's disabled but we still have data for a quiz.
			if ( 'yes' === this.lesson.get( 'quiz_enabled' ) || ! _.isEmpty( this.lesson.get( 'quiz' ) ) ) {

				this.model = this.lesson.get( 'quiz' );

				/**
				 * @todo  this is a terrible terrible patch
				 *        I've spent nearly 3 days trying to figure out how to not use this line of code
				 *        ISSUE REPRODUCTION:
				 *        Open course builder
				 *        Open a lesson (A) and add a quiz
				 *        Switch to a new lesson (B)
				 *        Add a new quiz
				 *        Return to lesson A and the quizzes parent will be set to LESSON B
				 *        This will happen for *every* quiz in the builder...
				 *        Adding this set_parent on init guarantees that the quizzes correct parent is set
				 *        after adding new quizzes to other lessons
				 *        it's awful and it's gross...
				 *        I'm confused and tired and going to miss release dates again because of it
				 */
				this.model.set_parent( this.lesson );

				this.listenTo( this.model, 'change:_points', this.render_points );

			}

			this.on( 'model-trashed', this.on_trashed );

		},

		/**
		 * Compiles the template and renders the view.
		 *
		 * @since 3.16.0
		 * @since 3.19.2 Unknown.
		 *
		 * @return {Self} For chaining.
		 */
		render: function() {

			this.$el.html( this.template( this.model ) );

			// Render the quiz builder.
			if ( this.model ) {

				// Don't allow interaction until questions are lazy loaded.
				LLMS.Spinner.start( this.$el );

				this.render_subview( 'settings', {
					el: '#llms-quiz-settings-fields',
					model: this.model,
				} );

				this.init_datepickers();
				this.init_selects();

				this.render_subview( 'bank', {
					collection: window.llms_builder.questions,
				} );

				var last_group = null,
					group = null;
				// Let all the question types reference the quiz for adding questions quickly.
				this.get_subview( 'bank' ).instance.viewManager.each( function( view ) {

					view.quiz = this.model;

					group = view.model.get( 'group' ).name;

					if ( last_group !== group ) {
						last_group = group;
						view.$el.before( '<li class="llms-question-bank-header"><h4>' + group + '</h4></li>' );
					}

				}, this );

				this.model.load_questions( _.bind( function( err ) {

					if ( err ) {
						alert( LLMS.l10n.translate( 'An error occurred while trying to load the questions. Please refresh the page and try again.' ) );
						return this;
					}

					LLMS.Spinner.stop( this.$el );
					this.render_subview( 'list', {
						el: '#llms-quiz-questions',
						collection: this.model.get( 'questions' ),
					} );
					var list = this.get_subview( 'list' ).instance;
					list.quiz = this;
					list.collection.on( 'add', function() {
						list.collection.trigger( 'reorder' );
					}, this );
					list.on( 'sortStart', list.sortable_start );
					list.on( 'sortStop', list.sortable_stop );

				}, this ) );

				this.model.on( 'new-question-added', function() {
					var $questions = this.$el.find( '#llms-quiz-questions' );
					$questions.animate( { scrollTop: $questions.prop( 'scrollHeight' ) }, 200 );
				}, this );

			}

			return this;

		},

		/**
		 * On quiz points update, update the value of the Total Points area in the header.
		 *
		 * @since 3.17.6
		 *
		 * @param {Object} quiz   Instance of the quiz model.
		 * @param {Int}    points Updated number of points.
		 * @return {Void}
		 */
		render_points: function( quiz, points ) {

			this.$el.find( '#llms-quiz-total-points' ).text( points );

		},

		/**
		 * Bulk expand / collapse question buttons.
		 *
		 * @since 3.16.0
		 *
		 * @param {Object} Event JS event object.
		 * @return {Void}
		 */
		bulk_toggle: function( event ) {

			var expanded = ( 'expand' === $( event.target ).attr( 'data-action' ) );

			this.model.get( 'questions' ).each( function( question ) {
				question.set( '_expanded', expanded );
			} );

		},

		/**
		 * Adds a new quiz to a lesson which currently has no quiz associated with it.
		 *
		 * @since 3.16.0
		 *
		 * @return {Void}
		 */
		add_new_quiz: function() {

			var quiz = this.lesson.get( 'quiz' );
			if ( _.isEmpty( quiz ) ) {
				quiz = this.lesson.add_quiz();
			} else {
				this.lesson.set( 'quiz_enabled', 'yes' );
			}

			this.model = quiz;
			this.render();

		},


		/**
		 * Add an existing quiz to a lesson.
		 *
		 * @since 3.16.0
		 * @since 3.24.0 Unknown.
		 * @since 5.4.0 Use author id instead of the quiz author object.
		 *
		 * @param {Object} event JS event object.
		 * @return {Void}
		 */
		add_existing_quiz: function( event ) {

			this.post_search_popover.hide();

			var quiz = event.data;

			if ( 'clone' === event.action ) {

				quiz = _.prepareQuizObjectForCloning( quiz );

			} else {

				// Use author id instead of the quiz author object.
				quiz = _.prepareExistingPostObjectDataForAddingOrCloning( quiz );
				quiz._forceSync = true;

			}

			delete quiz.lesson_id;

			this.lesson.add_quiz( quiz );
			this.model = this.lesson.get( 'quiz' );
			this.render();

		},

		/**
		 * Open add existing quiz popover.
		 *
		 * @since 3.16.12
		 *
		 * @param {Object} event JS event object.
		 * @return {Void}
		 */
		add_existing_quiz_click: function( event ) {

			event.preventDefault();

			this.post_search_popover = new Popover( {
				el: '#llms-existing-quiz',
				args: {
					backdrop: true,
					closeable: true,
					container: '.wrap.lifterlms.llms-builder',
					dismissible: true,
					placement: 'left',
					width: 480,
					title: LLMS.l10n.translate( 'Add Existing Quiz' ),
					content: new PostSearch( {
						post_type: 'llms_quiz',
						searching_message: LLMS.l10n.translate( 'Search for existing quizzes...' ),
					} ).render().$el,
					onHide: function() {
						Backbone.pubSub.off( 'quiz-search-select' );
					},
				}
			} );

			this.post_search_popover.show();
			Backbone.pubSub.once( 'quiz-search-select', this.add_existing_quiz, this );

		},

		// filter_question_types: _.debounce( function( event ) {

		// 	var term = $( event.target ).val();

		// 	this.QuestionBankView.viewManager.each( function( view ) {
		// 		if ( ! term ) {
		// 			view.clear_filter();
		// 		} else {
		// 			view.filter( term );
		// 		}
		// 	} );


		// }, 300 ),

		/**
		 * Callback function when the quiz has been deleted.
		 *
		 * @since 3.16.6
		 *
		 * @param {Oject} quiz Quiz Model.
		 * @return {Void}
		 */
		on_trashed: function( quiz ) {

			this.lesson.set( 'quiz_enabled', 'no' );
			this.lesson.set( 'quiz', '' );

			delete this.model;

			this.render();

		},

		/**
		 * "Add Question" button click event.
		 *
		 * @since 3.16.0
		 *
		 * Creates a popover with question type list interface.
		 *
		 * @return {Void}
		 */
		show_tools: function() {

			// Create popover,
			var pop = new Popover( {
				el: '#llms-show-question-bank',
				args: {
					backdrop: true,
					closeable: true,
					container: '#llms-builder-sidebar',
					dismissible: true,
					placement: 'top-left',
					width: 'calc( 100% - 40px )',
					title: LLMS.l10n.translate( 'Add a Question' ),
					url: '#llms-quiz-tools',
				}
			} );

			// Show it.
			pop.show();

			// If a question is added, hide the popover.
			this.model.on( 'new-question-added', function() {
				pop.hide();
			} );

		},

		get_question_list: function( options ) {
			return new QuestionList( options );
		}

	}, Detachable, Editable, Subview, Trashable, SettingsFields ) );

} );
