/**
 * Single Question View.
 *
 * @since 3.16.0
 * @version 7.8.0
 */
define( [
		'Views/_Detachable',
		'Views/_Editable',
		'Views/QuestionChoiceList'
	], function(
		Detachable,
		Editable,
		ChoiceListView
	) {

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

		/**
		 * Generate CSS classes for the question
		 * @return   string
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		className: function() {
			return 'llms-question qtype--' + this.model.get( 'question_type' ).get( 'id' );
		},

		events: _.defaults( {
			'click .clone--question': 'clone',
			'click .delete--question': 'delete',
			'click .expand--question': 'expand',
			'click .collapse--question': 'collapse',
			'change input[name="question_points"]': 'update_points',
		}, Detachable.events, Editable.events ),

		/**
		 * HTML element wrapper ID attribute
		 * @return   string
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		id: function() {
			return 'llms-question-' + this.model.id;
		},

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

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

		/**
		 * Initialization callback func (renders the element on screen)
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		initialize: function() {

			var change_events = [
				'change:_expanded',
				'change:menu_order',
			];
			_.each( change_events, function( event ) {
				this.listenTo( this.model, event, this.render );
			}, this );

			this.listenTo( this.model.get( 'image' ), 'change', this.render );

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

			this.on( 'multi_choices_toggle', this.multi_choices_toggle, this );

			Backbone.pubSub.on( 'del-question-choice', this.del_choice, this );

		},

		/**
		 * Compiles the template and renders the view.
		 *
		 * @since 3.16.0
		 * @since 7.8.0 Added support for image upload in tinyMCE editor.
		 *
		 * @return self (for chaining)
		 */
		render: function() {

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

			if ( this.model.get( 'question_type').get( 'choices' ) ) {

				this.choiceListView = new ChoiceListView( {
					el: this.$el.find( '.llms-question-choices' ),
					collection: this.model.get( 'choices' ),
				} );
				this.choiceListView.render();
				this.choiceListView.on( 'sortStart', this.choiceListView.sortable_start );
				this.choiceListView.on( 'sortStop', this.choiceListView.sortable_stop );

			}

			if ( 'group' === this.model.get( 'question_type' ).get( 'id' ) ) {

				var self = this;
				setTimeout( function() {
					self.questionListView = self.collectionListView.quiz.get_question_list( {
						el: self.$el.find( '.llms-quiz-questions' ),
						collection: self.model.get( 'questions' ),
					} );
					self.questionListView.render();
					self.questionListView.on( 'sortStart', self.questionListView.sortable_start );
					self.questionListView.on( 'sortStop', self.questionListView.sortable_stop );
				}, 1 );

			}

			if ( this.model.get( 'description_enabled' ) ) {
				this.init_editor( 'question-desc--' + this.model.get( 'id' ) );
			}

			if ( this.model.get( 'clarifications_enabled' ) ) {
				this.init_editor( 'question-clarifications--' + this.model.get( 'id' ), {
					mediaButtons: true,
					tinymce: {
						toolbar1: 'bold,italic,strikethrough,bullist,numlist,alignleft,aligncenter,alignright',
						toolbar2: '',
						setup: _.bind( this.on_editor_ready, this ),
					}
				} );
			}

			this.init_formatting_els();
			this.init_selects();

			return this;
		},

		/**
		 * rerender points percentage when question points are updated
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		render_points_percentage: function() {

			this.$el.find( '.llms-question-points' ).attr( 'data-tip', this.model.get_points_percentage() );

		},

		/**
		 * Click event to duplicate a question within a quiz
		 * @param    obj   event  js event object
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		clone: function( event ) {

			event.stopPropagation();
			event.preventDefault();
			this.model.collection.add( this._get_question_clone( this.model ) );

		},

		/**
		 * Recursive clone function which will correctly clone children of a question
		 * @param    obj   question  question model
		 * @return   obj
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		_get_question_clone: function( question ) {

			// create a duplicate
			var clone = _.clone( question.attributes );

			// remove id (we want the duplicate to have a temp id)
			delete clone.id;

			clone.parent_id = question.get( 'id' );

			// set the question type ID
			clone.question_type = question.get( 'question_type' ).get( 'id' );

			// clone the image attributes separately
			clone.image = _.clone( question.get( 'image' ).attributes );

			// if it has choices clone all the choices
			if ( question.get( 'choices' ) ) {

				clone.choices = [];

				question.get( 'choices' ).each( function ( choice ) {

					var choice_clone = _.clone( choice.attributes );
					delete choice_clone.id;
					delete choice_clone.question_id;

					clone.choices.push( choice_clone );

				} );

			}

			if ( 'group' === question.get( 'question_type' ).get( 'id' ) ) {

				clone.questions = [];
				question.get( 'questions' ).each( function( child ) {
					clone.questions.push( this._get_question_clone( child ) );
				}, this );

			}

			return clone;

		},

		/**
		 * Collapse a question and hide it's settings
		 * @param obj event js event obj.
		 * @return   void
		 * @since    3.16.0
		 * @version  3.27.0
		 */
		collapse: function( event ) {

			if ( event ) {
				event.preventDefault();
			}

			this.model.set( '_expanded', false );

		},

		/**
		 * Delete the question from a quiz / question group
		 * @param    obj   event  js event object
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		delete: function( event ) {

			event.preventDefault();

			if ( window.confirm( LLMS.l10n.translate( 'Are you sure you want to delete this question?' ) ) ) {

				this.model.collection.remove( this.model );
				Backbone.pubSub.trigger( 'model-trashed', this.model );

			}

		},

		/**
		 * Click event to reveal a question's settings & choices
		 * @param obj event js event obj.
		 * @return   void
		 * @since    3.16.0
		 * @version  3.27.0
		 */
		expand: function( event ) {

			if ( event ) {
				event.preventDefault();
			}

			this.model.set( '_expanded', true );

		},

		/**
		 * When toggling multiple correct answers *off* remove all correct choices except the first correct choice in the list
		 * @param    string   val  value of the question's `multi_choice` attr [yes|no]
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		multi_choices_toggle: function( val ) {

			if ( 'yes' === val ) {
				return;
			}

			this.model.get( 'choices' ).update_correct( _.first( this.model.get( 'choices' ).get_correct() ) );

		},

		/**
		 * Update the model's points when the value of the points input is updated
		 * @return   void
		 * @since    3.16.0
		 * @version  3.16.0
		 */
		update_points: function() {

			this.model.set( 'points', this.$el.find( 'input[name="question_points"]' ).val() * 1 );

		}

	}, Detachable, Editable ) );

} );
