/*
 * Copyright (C) 2011 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import I18n from 'i18n!question_bank'
import $ from 'jquery'
import find_outcome from './find_outcome'
import moveQuestionTemplate from 'jst/quiz/move_question'
import htmlEscape from './str/htmlEscape'
import moveMultipleQuestionBanks from 'jsx/quizzes/question_bank/moveMultipleQuestionBanks'
import loadBanks from 'jsx/quizzes/question_bank/loadBanks'
import addBank from 'jsx/quizzes/question_bank/addBank'
import './jquery.ajaxJSON'
import './jquery.instructure_forms' /* formSubmit, getFormData, formErrors */
import 'jqueryui/dialog'
import './jquery.instructure_misc_helpers' /* replaceTags */
import './jquery.instructure_misc_plugins' /* confirmDelete, showIf, .dim */
import './jquery.keycodes'
import './jquery.loadingImg'
import './jquery.templateData'

export function updateAlignments(alignments) {
  $('.add_outcome_text')
    .text(I18n.t('updating_outcomes', 'Updating Outcomes...'))
    .attr('disabled', true)
  const params = {}
  for (const idx in alignments) {
    const alignment = alignments[idx]
    params['assessment_question_bank[alignments][' + alignment[0] + ']'] = alignment[1]
  }
  if (alignments.length == 0) {
    params['assessment_question_bank[alignments]'] = ''
  }
  const url = $('.edit_bank_link:last').attr('href')
  $.ajaxJSON(
    url,
    'PUT',
    params,
    data => {
      const alignments = data.assessment_question_bank.learning_outcome_alignments.sort((a, b) => {
        const a_name = (
          (a.content_tag &&
            a.content_tag.learning_outcome &&
            a.content_tag.learning_outcome.short_description) ||
          'none'
        ).toLowerCase()
        const b_name = (
          (b.content_tag &&
            b.content_tag.learning_outcome &&
            b.content_tag.learning_outcome.short_description) ||
          'none'
        ).toLowerCase()
        if (a_name < b_name) {
          return -1
        } else if (a_name > b_name) {
          return 1
        } else {
          return 0
        }
      })
      $('.add_outcome_text')
        .text(I18n.t('align_outcomes', 'Align Outcomes'))
        .attr('disabled', false)
      const $outcomes = $('#aligned_outcomes_list')
      $outcomes.find('.outcome:not(.blank)').remove()
      const $template = $outcomes
        .find('.blank:first')
        .clone(true)
        .removeClass('blank')
      for (const idx in alignments) {
        const alignment = alignments[idx].content_tag
        const outcome = {
          short_description: alignment.learning_outcome.short_description,
          mastery_threshold: Math.round(alignment.mastery_score * 10000) / 100.0
        }
        const $outcome = $template.clone(true)
        $outcome.attr('data-id', alignment.learning_outcome_id)
        $outcome.fillTemplateData({
          data: outcome
        })
        $outcomes.append($outcome.show())
      }
    },
    data => {
      $('.add_outcome_text')
        .text(I18n.t('update_outcomes_fail', 'Updating Outcomes Failed'))
        .attr('disabled', false)
    }
  )
}

export function attachPageEvents(e) {
  $('#aligned_outcomes_list').delegate('.delete_outcome_link', 'click', function(event) {
    event.preventDefault()
    const result = confirm(
        I18n.t(
          'remove_outcome_from_bank',
          'Are you sure you want to remove this outcome from the bank?'
        )
      ),
      $outcome = $(event.target).parents('.outcome'),
      alignments = [],
      outcome_id = $outcome.data('id')

    if (result) {
      $outcome.dim()
      $('#aligned_outcomes_list .outcome:not(.blank)').each(function() {
        const id = $(this).attr('data-id')
        const pct =
          $(this).getTemplateData({textValues: ['mastery_threshold']}).mastery_threshold / 100
        if (id != outcome_id) {
          alignments.push([id, pct])
        }
      })
      updateAlignments(alignments)
    }
  })

  if ($('#more_questions').length > 0) {
    $('.display_question .move').remove()
    const url = $.replaceTags($('#bank_urls .more_questions_url').attr('href'), 'page', 1)
    $.ajaxJSON(
      url,
      'GET',
      {},
      data => {
        for (const idx in data.questions) {
          const question = data.questions[idx].assessment_question
          const $teaser = $('#question_teaser_' + question.id)
          $teaser.data('question', question)
        }
      },
      data => {}
    )
  }
  $('.more_questions_link').click(function(event) {
    event.preventDefault()
    if ($(this).hasClass('loading')) {
      return
    }
    const $link = $(this)
    const $more_questions = $('#more_questions')
    const currentPage = parseInt($more_questions.attr('data-current-page'))
    const totalPages = parseInt($more_questions.attr('data-total-pages'))
    let url = $(this).attr('href')
    url = $.replaceTags(url, 'page', currentPage + 1)
    $link.text('loading more questions...').addClass('loading')
    $.ajaxJSON(
      url,
      'GET',
      {},
      data => {
        $link.text(I18n.t('links.more_questions', 'more questions')).removeClass('loading')
        $more_questions.attr('data-current-page', currentPage + 1)
        $more_questions.showIf(currentPage + 1 < totalPages)
        for (const idx in data.questions) {
          const question = data.questions[idx].assessment_question
          question.assessment_question_id = question.id
          const $question = $('#question_teaser_blank')
            .clone()
            .removeAttr('id')
          $question.fillTemplateData({
            data: question,
            id: 'question_teaser_' + question.id,
            hrefValues: ['id']
          })
          $question.fillTemplateData({
            data: question.question_data,
            htmlValues: ['question_text']
          })
          $question.data('question', question)
          $question.find('.assessment_question_id').text(question.id)
          $('#questions').append($question)
          $question.show()
        }
      },
      () => {
        $link
          .text(I18n.t('loading_more_fail', 'loading more questions fails, please try again'))
          .removeClass('loading')
      }
    )
  })
  $('.delete_bank_link').click(function(event) {
    event.preventDefault()
    $(this)
      .parents('.question_bank')
      .confirmDelete({
        url: $(this).attr('href'),
        message: I18n.t(
          'delete_are_you_sure',
          'Are you sure you want to delete this bank of questions?'
        ),
        success() {
          location.href = $('.assessment_question_banks_url').attr('href')
        }
      })
  })
  $('.bookmark_bank_link').click(function(event) {
    event.preventDefault()
    const $link = $(this)
    $link.find('.message').text(I18n.t('bookmarking', 'Bookmarking...'))
    $.ajaxJSON(
      $(this).attr('href'),
      'POST',
      {},
      data => {
        $link.find('.message').text(I18n.t('already_bookmarked', 'Already Bookmarked'))
        $link.attr('disabled', true)
      },
      () => {
        $link.find('.message').text(I18n.t('bookmark_failed', 'Bookmark Failed'))
      }
    )
  })
  $('.edit_bank_link').click(event => {
    event.preventDefault()
    const val = $('#edit_bank_form h2').text()
    $('#edit_bank_form')
      .find('.displaying')
      .hide()
      .end()
      .find('.editing')
      .show()
    $('.bank_name_box')
      .val(val || I18n.t('question_bank', 'Question Bank'))
      .focus()
      .select()
  })
  $('#edit_bank_form .bank_name_box').keycodes('return esc', function(event) {
    if (event.keyString == 'esc') {
      $(this).blur()
    } else if (event.keyString == 'return') {
      $('#edit_bank_form').submit()
    }
  })
  $('#edit_bank_form .bank_name_box').blur(() => {
    $('#edit_bank_form')
      .find('.displaying')
      .show()
      .end()
      .find('.editing')
      .hide()
  })
  $('#edit_bank_form').formSubmit({
    object_name: 'assessment_question_bank',
    beforeSubmit(data) {
      $('#edit_bank_form h2').text(data.title)
      $(this).loadingImage()
    },
    success(data) {
      $(this).loadingImage('remove')
      const bank = data.assessment_question_bank
      $('#edit_bank_form .bank_name_box').blur()
      $('#edit_bank_form h2').text(bank.title)
    },
    error(data) {
      $(this).loadingImage('remove')
      $('.edit_bank_link').click()
      $('#edit_bank_form').formErrors(data)
    }
  })
  $('#show_question_details')
    .change(function() {
      $('#questions').toggleClass('brief', !$(this).attr('checked'))
    })
    .change()

  moveMultipleQuestionBanks.addEvents()

  $('#questions').delegate('.move_question_link', 'click', function(event) {
    event.preventDefault()
    const $dialog = $('#move_question_dialog')
    $dialog
      .find('.question_text')
      .show()
      .end()
      .find('.questions')
      .hide()
    $dialog.find('.copy_option').show()
    $dialog.find('.submit_button').text(I18n.t('title.move_copy_questions', 'Move/Copy Questions'))
    $dialog.find('.multiple_questions').val('0')
    if (!$dialog.hasClass('loaded')) {
      loadBanks($dialog)
    } else {
      $dialog.find('li.message').hide()
    }
    const template = $(this)
      .parents('.question_holder')
      .getTemplateData({textValues: ['question_name', 'question_text']})
    $dialog.fillTemplateData({
      data: template
    })
    $dialog.data('question', $(this).parents('.question_holder'))
    $dialog.dialog({
      width: 600,
      title: I18n.t('title.move_copy_questions', 'Move/Copy Questions')
    })
    $dialog
      .parent()
      .find('.ui-dialog-titlebar-close')
      .focus()
  })
  $('#move_question_dialog .submit_button').click(function() {
    const $dialog = $('#move_question_dialog')
    const data = $dialog.getFormData()
    const multiple_questions = data.multiple_questions == '1'
    const move = data.copy != '1'
    let submitText = null
    if (move) {
      submitText = I18n.t(
        'buttons.submit_moving',
        {one: 'Moving Question...', other: 'Moving Questions...'},
        {count: multiple_questions ? 2 : 1}
      )
    } else {
      submitText = I18n.t(
        'buttons.submit_copying',
        {one: 'Copying Question...', other: 'Copying Questions...'},
        {count: multiple_questions ? 2 : 1}
      )
    }
    $dialog.find('button').attr('disabled', true)
    $dialog.find('.submit_button').text(submitText)
    const url = $('#bank_urls .move_questions_url').attr('href')
    data.move = move ? '1' : '0'
    if (!multiple_questions) {
      const id = $dialog
        .data('question')
        .find('.assessment_question_id')
        .text()
      data['questions[' + id + ']'] = '1'
    }
    const ids = []
    $dialog.find('.list_question :checkbox:checked').each(function() {
      ids.push($(this).val())
    })
    const save = function(data) {
      $.ajaxJSON(
        url,
        'POST',
        data,
        data => {
          $dialog.find('button').attr('disabled', false)
          $dialog.find('.submit_button').text('Move/Copy Question')
          if (move) {
            if ($dialog.data('question')) {
              $dialog.data('question').remove()
            } else {
              for (const idx in ids) {
                const id = ids[idx]
                $('#question_' + id)
                  .parent('.question_holder')
                  .remove()
                $('#question_teaser_' + id).remove()
              }
              $dialog.find
            }
          }
          $dialog.dialog('close')
        },
        data => {
          $dialog.find('button').attr('disabled', false)
          let failedText = null
          if (move) {
            failedText = I18n.t(
              'buttons.submit_moving_failed',
              {
                one: 'Moving Question Failed, please try again',
                other: 'Moving Questions Failed, please try again'
              },
              {count: multiple_questions ? 2 : 1}
            )
          } else {
            failedText = I18n.t(
              'buttons.submit_copying_failed',
              {
                one: 'Copying Question Failed, please try again',
                other: 'Copying Questions Failed, please try again'
              },
              {count: multiple_questions ? 2 : 1}
            )
          }
          $dialog.find('.submit_button').text(failedText)
        }
      )
    }
    if (data.assessment_question_bank_id == 'new') {
      const create_url = $('#bank_urls .assessment_question_banks_url').attr('href')
      $.ajaxJSON(
        create_url,
        'POST',
        {'assessment_question_bank[title]': data.assessment_question_bank_name},
        bank_data => {
          addBank(bank_data.assessment_question_bank)
          data.assessment_question_bank_id = bank_data.assessment_question_bank.id
          $dialog.find('.new_question_bank_name').hide()
          save(data)
        },
        data => {
          $dialog.find('button').attr('disabled', false)
          let submitAgainText = null
          if (move) {
            submitAgainText = I18n.t(
              'buttons.submit_retry_moving',
              'Moving Question Failed, please try again...'
            )
          } else {
            submitAgainText = I18n.t(
              'buttons.submit_retry_copying',
              'Copying Question Failed, please try again...'
            )
          }
          $dialog.find('.submit_button').text(submitAgainText)
        }
      )
    } else {
      save(data)
    }
  })
  $('#move_question_dialog .cancel_button').click(() => {
    $('#move_question_dialog').dialog('close')
  })
  $('#move_question_dialog :radio').change(function() {
    $('#move_question_dialog .new_question_bank_name').showIf(
      $(this).attr('checked') && $(this).val() == 'new'
    )
  })
}
