app = require 'core/application'
CreateAccountModal = require 'views/core/CreateAccountModal'
CocoCollection = require 'collections/CocoCollection'
Course = require 'models/Course'
RootView = require 'views/core/RootView'
stripeHandler = require 'core/services/stripe'
template = require 'templates/courses/course-enroll'
utils = require 'core/utils'

module.exports = class CourseEnrollView extends RootView
  id: 'course-enroll-view'
  template: template

  events:
    'click .btn-buy': 'onClickBuy'
    'change .class-name': 'onNameChange'
    'change .course-select': 'onChangeCourse'
    'change .input-seats': 'onSeatsChange'
    'change #programming-language-select': 'onChangeProgrammingLanguageSelect'

  subscriptions:
    'stripe:received-token': 'onStripeReceivedToken'

  constructor: (options, @courseID) ->
    super options
    @courseID ?= options.courseID
    @seats = 20
    @selectedLanguage = 'python'

    @courses = new CocoCollection([], { url: "/db/course", model: Course})
    @listenTo @courses, 'sync', @onCoursesLoaded
    @supermodel.loadCollection(@courses, 'courses')

  afterRender: ->
    super()
    if @selectedCourse
      @$el.find('.course-select').val(@selectedCourse.id)
    else
      @$el.find('.course-select').val('All Courses')

  onCoursesLoaded: ->
    if @courseID
      @selectedCourse = _.find @courses.models, (a) => a.id is @courseID
    else if @courses.models.length > 0
      @selectedCourse = @courses.models[0]
    @renderNewPrice()

  onClickBuy: (e) ->
    return @openModalView new CreateAccountModal() if me.isAnonymous()

    if @price is 0
      @seats = 9999
      @state = 'creating'
      @createClass()
      return

    if @seats < 1 or not _.isFinite(@seats)
      alert("Please enter the maximum number of students needed for your class.")
      return

    @state = undefined
    @stateMessage = undefined
    @render()

    # Show Stripe handler
    courseTitle = @selectedCourse?.get('name') ? 'All Courses'
    application.tracker?.trackEvent 'Started course purchase', {course: courseTitle, price: @price, seats: @seats}
    stripeHandler.open
      amount: @price
      description: "#{courseTitle} for #{@seats} students"
      bitcoin: true
      alipay: if me.get('country') is 'china' or (me.get('preferredLanguage') or 'en-US')[...2] is 'zh' then true else 'auto'

  onStripeReceivedToken: (e) ->
    @state = 'purchasing'
    @render?()
    @createClass(e.token.id)

  onChangeCourse: (e) ->
    @selectedCourse = _.find @courses.models, (a) -> a.id is $(e.target).val()
    @renderNewPrice()

  onChangeProgrammingLanguageSelect: (e) ->
    @selectedLanguage = @$('#programming-language-select').val()

  onNameChange: (e) ->
    @className = $('.class-name').val()

  onSeatsChange: (e) ->
    @seats = $(e.target).val()
    @seats = 20 if @seats < 1 or not _.isFinite(@seats)
    @renderNewPrice()

  createClass: (token) ->
    data =
      name: @className
      seats: @seats
      stripe:
        token: token
        timestamp: new Date().getTime()
      aceConfig: { language: @selectedLanguage }

    data.courseID = @selectedCourse.id if @selectedCourse
    jqxhr = $.post('/db/course_instance/-/create', data)
    jqxhr.done (data, textStatus, jqXHR) =>
      application.tracker?.trackEvent 'Finished course purchase', {course: @selectedCourse?.get('name') ? 'All Courses', price: @price, seats: @seats}
      # TODO: handle fetch errors
      me.fetch(cache: false).always =>
        courseID = @selectedCourse?.id ? @courses.models[0]?.id
        route = "/students/#{courseID}"
        viewArgs = [{}, courseID]
        if data?.length > 0
          courseInstanceID = data[0]._id
          route += "/#{courseInstanceID}"
          viewArgs[0].courseInstanceID = courseInstanceID
        Backbone.Mediator.publish 'router:navigate',
          route: route
          viewClass: 'views/courses/CourseDetailsView'
          viewArgs: viewArgs
    jqxhr.fail (xhr, textStatus, errorThrown) =>
      console.error 'Got an error purchasing a course:', textStatus, errorThrown
      application.tracker?.trackEvent 'Failed course purchase', status: textStatus
      if xhr.status is 402
        @state = 'declined'
        @stateMessage = arguments[2]
      else
        @state = 'unknown_error'
        @stateMessage = "#{xhr.status}: #{xhr.responseText}"
      @render?()

  renderNewPrice: ->
    if @selectedCourse
      coursePrices = [@selectedCourse.get('pricePerSeat')]
    else
      coursePrices = (c.get('pricePerSeat') for c in @courses.models)
    @price = utils.getCourseBundlePrice(coursePrices, @seats)
    @price = 0 if me.isAdmin()
    @render?()
