context = window
rest = context.JK.Rest()
logger = context.JK.logger
LocationActions = context.LocationActions
AppStore = context.AppStore
UserStore = context.UserStore
SubscriptionActions = context.SubscriptionActions


profileUtils = context.JK.ProfileUtils

@AccountPaymentHistoryScreen = React.createClass({

  mixins: [
    ICheckMixin,
    Reflux.listenTo(AppStore, "onAppInit"),
    Reflux.listenTo(UserStore, "onUserChanged"),
    Reflux.listenTo(@LocationStore, "onLocationsChanged"),
    Reflux.listenTo(SubscriptionStore, "onSubscriptionChanged")
  ]

  shownOnce: false
  screenVisible: false

  LIMIT: 20
  TILE_PAYMENTS_TO_YOU: 'payments to you'
  TILE_PAYMENTS_TO_JAMKAZAM: 'payments to jamkazam'
  TILE_PAYMENT_METHOD: 'payment method'

  STUDENT_TILES: ['payment method', 'payments to jamkazam']
  TEACHER_TILES: ['payments to jamkazam', 'payments to you']

  onAppInit: (@app) ->
    @app.bindScreen('account/paymentHistory', {beforeShow: @beforeShow, afterShow: @afterShow, beforeHide: @beforeHide})

  onUserChanged: (userState) ->
    if !@shouldShowNameSet
      @shouldShowNameSet = true
      if userState?.user?
        username = userState.user.name
        first_name = userState.user.first_name
        last_name = userState.user.last_name
        shouldShowName = !username? || username.trim() == '' || username.toLowerCase().indexOf('anonymous') > -1
    else
      shouldShowName = @state.shouldShowName

    if userState?.user?.teacher?
      @setState({selected: 'payments to you'})

    @setState({user: userState?.user, shouldShowName: shouldShowName})


  componentDidMount: () ->
    #@checkboxes = [{selector: 'input.billing-address-in-us', stateKey: 'billingInUS'}]

    @root = $(@getDOMNode())
    @endOfList = @root.find('.end-of-payments-list')
    @contentBodyScroller = @root
    #@iCheckify()
    @preparePaymentMethod()

  componentDidUpdate: (prevProps, prevState) ->
    #@iCheckify()

    #$expiration = @root.find('input.expiration')
    #if !$expiration.data('payment-applied')
    #  $expiration.payment('formatCardExpiry').data('payment-applied', true)
    #$cardNumber = @root.find("input.card-number")
    #if !$cardNumber.data('payment-applied')
    #  $cardNumber.payment('formatCardNumber').data('payment-applied', true)
    #$cvv = @root.find("input.cvv")
    #if !$cvv.data('payment-applied')
    #  $cvv.payment('formatCardCVC').data('payment-applied', true)

    if @currentNext() == null
      @contentBodyScroller.off('scroll')
      if @state[@getCurrentPageName()] == 1 and @getCurrentList().length == 0
        @endOfList.show()
        logger.debug("PaymentHistoryScreen: empty search")
      else if @state[@getCurrentPageName()] > 0
        logger.debug("end of search")
        @endOfList.show()
    else
      @registerInfiniteScroll(@contentBodyScroller)

    if @activeTile(prevState.selected) != @activeTile() && @getCurrentList().length == 0
      @refresh()

    @configureElements()


  registerInfiniteScroll:() ->
    $scroller = @contentBodyScroller
    logger.debug("registering infinite scroll")
    $scroller.off('scroll')
    $scroller.on('scroll', () =>
      # be sure to not fire off many refreshes when user hits the bottom
      return if @refreshing

      if $scroller.scrollTop() + $scroller.innerHeight() + 100 >= $scroller[0].scrollHeight
        #$scroller.append('<div class="infinite-scroll-loader-2">... Loading more Payments ...</div>')
        @setState({searching: true})
        logger.debug("refreshing more payments for infinite scroll")
        @nextPage()
    )

  nextPage: () ->
    #nextPage = @state.salesCurrentPage + 1
    @incrementCurrentPage()
    @refresh()

  checkboxChanged: (e) ->
    checked = $(e.target).is(':checked')

    value = $(e.target).val()

    @setState({userSchedulingComm: value})

  beforeHide: (e) ->
    @screenVisible = false
    @resetErrors()

  beforeShow: (e) ->

  afterShow: (e) ->
    @clearResults()
    @screenVisible = true
    @refresh()
    #@getUncollectables()

  resetErrors: () ->
    @setState({ccError: null, cvvError: null, expiryError: null, billingInUSError: null, zipCodeError: null, nameError: null, firstNameError: null, lastNameError: null, cityError: null, stateError: null, address1Error: null, countryError: null, address2Error:null})

  onBack: (e) ->
    e.preventDefault()

    window.history.go(-1);

  checkboxChanged: (e) ->
    checked = $(e.target).is(':checked')

    @setState({billingInUS: checked})

  refresh: () ->
    @buildQuery()
    if @activeTile() == @TILE_PAYMENTS_TO_YOU
      @refreshTeacherDistributions()
    else if @activeTile() == @TILE_PAYMENTS_TO_JAMKAZAM
      @refreshSales()
    else if @activeTile() == @TILE_PAYMENT_METHOD
      @refreshPayment()
    else
      logger.debug("dropping refresh because no tile match", @activeTile)

  refreshPayment:() ->
    SubscriptionActions.updateSubscription()

  refreshSales: () ->
    @refreshing = true
    #rest.getSalesHistory(@currentQuery)
    #.done(@salesHistoryDone)
    #.fail(@salesHistoryFail)


    rest.listInvoices()
    .done(@paymentHistoryDone)
    .fail(@paymentHistoryFail)

  refreshTeacherDistributions: () ->
    @refreshing = true
    rest.listTeacherDistributions(@currentQuery)
    .done(@teacherDistributionsDone)
    .fail(@teacherDistributionsFail)

  getUncollectables: () ->
    rest.getUncollectables({})
    .done(@uncollectablesDone)
    .fail(@uncollectablesFail)

  salesHistoryDone:(response) ->
    @refreshing = false
    this.setState({salesNext: response.next, sales:  this.state.sales.concat(response.entries)})

  salesHistoryFail:(jqXHR) ->
    @refreshing = false
    @app.notifyServerError jqXHR, 'Payments to JamKazam Unavailable'

  paymentHistoryDone:(response) ->
    @refreshing = false
    this.setState({salesNext: null, sales:  this.state.sales.concat(response.entries), pastDue: response.past_due})

  paymentHistoryFail:(jqXHR) ->
    @refreshing = false
    @app.notifyServerError jqXHR, 'Payments to JamKazam Unavailable'

  teacherDistributionsDone:(response) ->
    @refreshing = false
    this.setState({distributionsNext: response.next, distributions:  this.state.distributions.concat(response.entries)})

  teacherDistributionsFail:(jqXHR) ->
    @refreshing = false
    @app.notifyServerError jqXHR, 'Payments to You Unavailable'

  uncollectablesDone: (response) ->
    this.setState({uncollectables: response})

  uncollectablesFail: (jqXHR) ->
    @app.notifyServerError jqXHR, 'Unable to fetch uncollectable info'

  clearResults:() ->
    this.setState({salesCurrentPage: 0, sales: [], distributionsCurrentPage: 0, distributions: [], salesNext: null, distributionsNext: null, updating: false, pastDue: false})

  buildQuery:(page = @getCurrentPage()) ->
    @currentQuery = this.defaultQuery(page)

  defaultQuery:(page = @getCurrentPage()) ->
    query =
      per_page: @LIMIT
      page: page + 1
    if @currentNext()
      query.page = @currentNext()
    query

  getCurrentPage: () ->
    page = this.state[@getCurrentPageName()]
    if !page?
      page = 1
    page

  incrementCurrentPage: () ->
    newState = {}
    newState[@getCurrentPageName] = @state[@getCurrentPageName()] + 1
    this.setState(newState)

  getCurrentPageName: () ->
    if @activeTile() == @TILE_PAYMENTS_TO_JAMKAZAM
      'salesCurrentPage'
    else if @activeTile() == @TILE_PAYMENTS_TO_YOU
      'distributionsCurrentPage'
    else
      1

  getCurrentList: () ->
    if @activeTile() == @TILE_PAYMENTS_TO_JAMKAZAM
      @state['sales']
    else if @activeTile() == @TILE_PAYMENTS_TO_YOU
      @state['distributions']
    else
      @state['sales']

  currentNext: () ->
    if @activeTile() == @TILE_PAYMENTS_TO_JAMKAZAM
      @state.salesNext
    else if @activeTile() == @TILE_PAYMENTS_TO_YOU
      @state.distributionsNext
    else
      null

  onClick: (e) ->
    e.preventDefault()

    context.location.href = '/client#/account'
  getInitialState: () ->
    {
      user: null,
      nextPager: null,
      salesCurrentPage: 0,
      distributionsCurrentPage: 0
      salesNext:  null,
      distributionsNext: null
      sales: [],
      distributions: []
      selected: @TILE_PAYMENT_METHOD,
      updating: false,
      billingInUS: true,
      userWantsUpdateCC: false,
      selectedCountry: null,
      paypal_updating: false,
      uncollectables: []
    }

  onCancel: (e) ->
    e.preventDefault()
    context.location.href = '/client#/account'


  mainContent: () ->
    if !@state.user?
      `<div className="loading">Loading...</div>`
    else if @state.selected == @TILE_PAYMENTS_TO_YOU
      @paymentsToYou()
    else if @state.selected == @TILE_PAYMENTS_TO_JAMKAZAM
      @paymentsToJamKazam()
    else if @state.selected == @TILE_PAYMENT_METHOD
      @paymentMethod()
    else
      @paymentsToJamKazam()

  paymentsToYou: () ->
    rows = []

    for paymentHistory in @getCurrentList()
      paymentMethod = 'Stripe'

      if paymentHistory.distributed
        date = paymentHistory.teacher_payment.teacher_payment_charge.last_billing_attempt_at
        status = 'Paid'
      else
        date = paymentHistory.created_at
        if paymentHistory.not_collectable
          status = 'Uncollectible'
        else if !paymentHistory.teacher?.teacher?.stripe_account_id?
          status = 'No Stripe Acct'
        else
          status = 'Collecting'


      date = context.JK.formatDate(date, true)
      description = paymentHistory.description

      if paymentHistory.teacher_payment?
        amt = paymentHistory.teacher_payment.real_distribution_in_cents
      else
        amt = paymentHistory.real_distribution_in_cents

      displayAmount = ' $' + (amt/100).toFixed(2)

      amountClasses = {status: status}

      row =
        `<tr>
          <td>{date}</td>
          <td className="capitalize">{paymentMethod}</td>
          <td>{description}</td>
          <td className="capitalize">{status}</td>
          <td className={classNames(amountClasses)}>{displayAmount}</td>
        </tr>`
      rows.push(row)

    `<div>
      <table className="payment-table">
        <thead>
        <tr>
          <th>DATE</th>
          <th>METHOD</th>
          <th>DESCRIPTION</th>
          <th>STATUS</th>
          <th>AMOUNT</th>
        </tr>
        </thead>
        <tbody>
        {rows}
        </tbody>

      </table>
      <a className="btn-next-pager" href="/api/sales?page=1">Next</a>
      <div className="end-of-payments-list end-of-list">No more payment history</div>
      <div className="input-aligner">
        <a className="back button-grey" onClick={this.onBack}>BACK</a>
      </div>
      <br className="clearall" />
    </div>`


  onSubscriptionChanged: (subscription) ->
    @setState({pastDue: subscription.past_due})

  onLocationsChanged: (countries) ->
    console.log("countries in ", countries)
    @setState({countries: countries})

  onCountryChanged: (e) ->
    val = $(e.target).val()
    @setState({selectedCountry: val})

  currentCountry: () ->
    this.state.selectedCountry || this.props.selectedCountry || ''


  openBrowser: () ->
    context.JK.popExternalLink("https://www.jamkazam.com/client#/subscription")

  onRecurlyToken: (err, token_data) ->

    if err
      console.log("error", err)

      handled = false
      if err.code == "validation" && err.fields?
        handled = true
        for field in err.fields
          console.log("problem field", field)
          # handle error using err.code and err.fields
          if field == "first_name"
            @setState({firstNameError: true})
          if field == "last_name"
            @setState({lastNameError: true})
      if err.code == "invalid-parameter"
        if err.fields.indexOf("year") > -1 || err.fields.indexOf("month") > -1 || err.fields.indexOf("number") > -1 || err.fields.indexOf("cvv") > -1
          @setState({ccError: true})
          handled = true

        @app.layout.notify({title: 'Please double-check ' + err.fields[0], text: err.message})
      if !handled
        @app.layout.notify({title: "Error Updating Payment Info", text: JSON.stringify(err)})
      @setState({updating: false})
    else
      # recurly.js has filled in the 'token' field, so now we can submit the
      # form to your server
      console.log("eintercepted", token_data)
      rest.updatePayment({recurly_token: token_data.id}).done((response) => @updatePaymentDone(response)).fail((jqXHR) => @updatePaymentFailure(jqXHR))

  updatePaymentDone: (response) ->
    @setState({updating: false, "paypal_updating": false})

    logger.debug("recurly submitted: " + JSON.stringify(response))

    @setState({userWantsUpdateCC: false})

    #if @state.shouldShowName
    window.UserActions.refresh()

    if response.uncollectables
      context.JK.Banner.showAlert('Credit Card Updated', 'Than you. Your credit card info has been updated.<br/><br/>We will try to bill any unpaid lessons within the next hour, and an email will be sent at that time.')
    else
      @app.layout.notify({title: 'Payment Updated', text: 'Your payment info has been updated.'})

  updatePaymentFailure: (jqXHR) ->
    @setState({updating: false, "paypal_updating": false})
    handled = false
    if jqXHR.status == 404
      errors = JSON.parse(jqXHR.responseText)?.message
      @app.layout.notify({title: "Error Updating Payment Info", text: errors})
    else
      @app.notifyServerError(jqXHR, 'Payment Not Updated')

  onFormSubmit: (event) ->
    form = event.target
    console.log("ok work this", form)
    event.preventDefault()
    @setState({updating: true})
    recurly.token(@elements, form, @onRecurlyToken)

  configureRecurly: () ->
    if !window.configuredRecurly
      console.log("configuring recurly...")
      window.recurly.configure(gon.global.recurly_public_api_key)
      window.configuredRecurly = true
      @setState({"configuredRecurly": true})
      @elements = window.recurly.Elements()

      # then load paypal:
      @paypal = window.recurly.PayPal({ braintree: { clientAuthorization: gon.global.braintree_token} })
      @paypal.on('error', this.onPayPalError)
      @paypal.on('token', this.onPayPalToken)

  delayedConfigure: () ->
    if gon.isNativeClient
      return
    if  !window.recurly?
      console.log("relaunch delayed recurly configure")
      setTimeout(() =>
        @delayedConfigure()
      , 1000)
      return

    @configureRecurly()
    @configureElements()

  configureElements: () ->

    node = $('#subscription-elements')
    if node.length > 0
      if window.recurly && @elements? && !node.data('recurlied')
        commonStyles = {
          inputType: 'mobileSelect',
          style: {
            fontSize:'1em'
            color:'black',
            placeholder: {
              color:'black',
            }
            invalid: {
              fontColor: 'red'
            }
          }
        }

        #cardNumberStyle = $.extend(true, {}, commonStyles, {style:{placeholder:{content: 'Card Number'}}})
        #cardMonthStyle = $.extend(true, {}, commonStyles, {style:{placeholder:{content: 'MM'}}})
        #cardYearStyle = $.extend(true, {}, commonStyles, {style:{placeholder:{content: 'YYYY'}}})
        #cardCvcStyle = $.extend(true, {}, commonStyles, {style:{placeholder:{content: 'CVC'}}})

        #cardNumberElement = @elements.CardNumberElement( cardNumberStyle )
        #cardMonthElement = @elements.CardMonthElement(cardMonthStyle)
        #cardYearElement = @elements.CardYearElement(cardYearStyle)
        #cardCvvElement = @elements.CardCvvElement(cardCvcStyle)

        #cardNumberElement.attach('#subscription-elements-number')
        #cardMonthElement.attach('#subscription-elements-month')
        #cardYearElement.attach('#subscription-elements-year')
        #cardCvvElement.attach('#subscription-elements-cvv')

        cardElement = @elements.CardElement(commonStyles)
        cardElement.attach("#subscription-elements")

        document.querySelector('#user-payment-submit').addEventListener('submit', @onSubmit.bind(this))
        node.data('recurlied', true)

  preparePaymentMethod: () ->
    LocationActions.load()

    setTimeout(() =>
      @delayedConfigure()
    , 200)

  defaultText: () ->
    'Select Country'

  onStartPaypal: (e) ->
    e.preventDefault()
    if @state.updating
      return
    @setState({"paypal_updating": true})
    @paypal.start()

  onPayPalToken:(token) ->
    console.log("OnPayPalToken", token)
    @setState({updating: true})
    rest.updatePayment({recurly_token: token.id}).done((response) => @updatePaymentDone(response)).fail((jqXHR) => @updatePaymentFailure(jqXHR))

  onPayPalError: (err) ->
    console.error("OnPayPalError", err)
    @setState({"paypal_updating": false})

  openBrowserToPayment: () ->
    context.JK.popExternalLink("/client#/account/paymentHistory", true)

  paymentMethod: () ->
    if context.jamClient.IsNativeClient()
      return `<div>
          <div classNames="column column-left">
              <p>Updating payment is only supported in a web browser.   Please click the button below to open this page in your system web browser.</p>
              <p style={{textAlign: "center"}}>
              <a className="button-orange" href='#' onClick={this.openBrowserToPayment}>UPDATE PAYMENT METHOD</a>
              </p>
          </div>
          <br className="clearall"/>
      </div>`

    disabled = @state.updating || @reuseStoredCard()

    submitClassNames = {'button-orange': true, 'purchase-btn': true, disabled: disabled && @state.updating}
    updateCardClassNames = {'button-grey': true, 'update-btn': true, disabled: disabled && @state.updating}
    backClassNames = {'button-grey': true, disabled: disabled && @state.updating}

    cardNumberFieldClasses = {field: true, "card-number": true, error: @state.ccError}
    expirationFieldClasses = {field: true, "expiration": true, error: @state.expiryError}
    cvvFieldClasses = {field: true, "card-number": true, error: @state.cvvError}
    inUSClasses = {field: true, "billing-in-us": true, error: @state.billingInUSError}
    zipCodeClasses = {field: true, "zip-code": true, error: @state.zipCodeError}
    nameClasses= {field: true, "name": true, error: @state.nameError}
    firstNameClasses= {field: true, "first-name": true, error: @state.firstNameError}
    lastNameClasses= {field: true, "last-name": true, error: @state.lastNameError}
    address1Classes= {field: true, "address-1": true, error: @state.address1Error}
    address2Classes= {field: true, "address-2": true, error: @state.address2Error}
    cityClasses= {field: true, "city": true, error: @state.cityError}
    stateClasses= {field: true, "state": true, error: @state.stateError}
    countryClasses = {field: true, "country": true, error: @state.countryError}

    formClasses= {stored: @reuseStoredCard()}
    leftColumnClasses = {column: true, 'column-left': true, stored: @reuseStoredCard()}
    rightColumnClasses = {column: true, 'column-right': true, stored: @reuseStoredCard()}

    if @state.countries?
      countries = [`<option key="" value="">{this.defaultText()}</option>`]
      for countryId, countryInfo of @state.countries
        countries.push(`<option key={countryId} value={countryId}>{countryInfo.name}</option>`)

      country = @state.countries[this.currentCountry()]
    else
      countries = []

    countryJsx = `
        <select  disabled={disabled} name="countries" onChange={this.onCountryChanged} value={this.currentCountry()} data-recurly="country" autoComplete="shipping country" className="country">{countries}</select>`


    if gon.global.paypal_admin_only
      if @state.user?.admin
        paypal_visibility = 'block'
      else
        paypal_visibility = 'none'
    else
      paypal_visibility = 'block'


    paypalButtonClasses = "paypal-button "
    if !@state.configuredRecurly
      paypalButtonText = `<span className="paypal-txt">Loading PayPal ...</span>`
      paypalButtonClasses = paypalButtonClasses + "paypal-updating"
    else if @state.paypal_updating && @state.updating
      paypalButtonClasses = paypalButtonClasses + "paypal-updating"
      paypalButtonText = `<span className="paypal-txt">Updating your account ...</span>`
    else
      paypalButtonText = `<img src="https://www.paypalobjects.com/webstatic/en_US/i/buttons/PP_logo_h_100x26.png" alt="PayPal" />`
    if @state.uncollectables.length > 0
      uncollectable = @state.uncollectables[0]
      uncollectableMessage = `<div className="uncollectable-msg">A charge for your music lesson with {uncollectable.teacher.name} failed. Please update your credit card information immediately so that we can pay the instructor. If you have called your credit card provider and believe there should be no problem with your card, please email us at <a href="mailto:support@jamkazam.com">support@jamkazam.com</a> so that we can figure out what's gone wrong. Thank you!</div>`

    if @state.pastDue
      uncollectableMessage = `<div className="uncollectable-msg">A charge for your subscription has failed. Please update your credit card information immediately so that you can restore your plan.</div>`
    if @state.user?['has_stored_credit_card?'] && @state.uncollectables.length == 0
      if @state.userWantsUpdateCC
        header = 'Please update your billing address and payment information below.'
        updateCardAction = `<a className={classNames(updateCardClassNames)} onClick={this.onLockPaymentInfo}>NEVERMIND</a>`
        actions = `<div className="actions">
          <a className={classNames(backClassNames)} onClick={this.onBack}>BACK</a>
          {updateCardAction}
          <a className={classNames(submitClassNames)} onClick={this.onSubmitForm}>SUBMIT CARD INFORMATION</a>
        </div>`
      else
        header = 'You have have a payment method on file already.'
        updateCardAction = `<a className={classNames(updateCardClassNames)} onClick={this.onUnlockPaymentInfo}>I'D LIKE TO UPDATE MY PAYMENT INFO</a>`
        managedSubscriptionAction = `<a href="/client#/account/subscription" className="button-orange">MANAGE MY SUBSCRIPTION</a>`
        actions = `<div className="actions">
          <a className={classNames(backClassNames)} onClick={this.onBack}>BACK</a>
          {updateCardAction}
          {managedSubscriptionAction}
        </div>`
    else
      header = `<div>Please enter your billing address and payment information below.<br/><br/><span className="no-storage-note">This information is sent to <a href="https://recurly.com/customers/" rel="external">Recurly</a>, which is compliant with the PCI-DSS security standard. JamKazam does not receive or store your credit card.</span></div>`
      actions = `<div className="actions">
        <a className={classNames(backClassNames)} onClick={this.onBack}>BACK</a><a
        className={classNames(submitClassNames)} onClick={this.onSubmitForm}>SUBMIT CARD INFORMATION</a>
      </div>`

    firstNameField =
      `<div className={classNames(firstNameClasses)}>
          <label>First Name:</label>
          <input disabled={disabled} type="text" name="first_name" className="first_name" data-recurly="first_name" required autoComplete="cc-given-name"></input>
      </div>`
    lastNameField =
      `<div className={classNames(lastNameClasses)}>
          <label>Last Name:</label>
          <input disabled={disabled} type="text" name="last_name" className="last_name" data-recurly="last_name" required autoComplete="cc-surname"></input>
      </div>`

    `<div>
      <div className={classNames(leftColumnClasses)}>
        {uncollectableMessage}
        <div className="paymethod-header">{header}</div>
        <form autoComplete="on" onSubmit={this.onSubmit} className={classNames(formClasses)} id="user-payment-submit">
          {firstNameField}
          {lastNameField}
          <div className={classNames(address1Classes)}>
              <label>Address 1:</label>
              <input type="text" data-recurly="address1"  disabled={disabled} required autoComplete="shipping address-line1" className="address-1"></input>
          </div>
          <div className={classNames(address2Classes)}>
              <label>Address 2:</label>
              <input type="text" data-recurly="address2"  disabled={disabled} autoComplete="shipping address-line2" className="address-2"></input>
          </div>
          <div className={classNames(cityClasses)}>
            <label for="city">City:</label>
            <input type="text" data-recurly="city"  className="city" disabled={disabled} required autoComplete="shipping address-level2"></input>
          </div>
            <div className={classNames(stateClasses)}>
            <label for="state">State:</label>
            <input type="text" data-recurly="state"  className="state" disabled={disabled} required autoComplete="shipping address-level1"></input>
          </div>
          <div className={classNames(zipCodeClasses)}>
            <label>Postal Code:</label>
            <input type="text" name="zip" data-recurly="postal_code" disabled={disabled} required autoComplete="shipping postal-code"
                   className="zip"></input>
          </div>
          <div className={classNames(countryClasses)}>
              <label for="country">Country:</label>
              {countryJsx}
          </div>
          <div className={classNames(cardNumberFieldClasses)}>
              <label>Card:</label>
              <span className="recurly-holder" id="subscription-elements"></span>
          </div>

          <input type="hidden" name="recurly-token" data-recurly="token"></input>

          <div className="paypal-region" style={{display: paypal_visibility}}>
              <div className="or-use-paypal">Or Use PayPal:</div>
              <a href="/paypal/checkout/start" className={paypalButtonClasses} onClick={this.onStartPaypal}>
                  {paypalButtonText}
              </a>
          </div>
        </form>
        {actions}
      </div>
      <br className="clearall"/>
    </div>`

  paymentsToJamKazam: () ->
    rows = []
    uncollectables = []

    for uncollectable in @state.uncollectables
      date = context.JK.formatDate(uncollectable.last_billed_at_date, true)
      paymentMethod = 'Credit Card'
      amt = uncollectable.expected_price_in_cents
      displayAmount = ' $' + (amt/100).toFixed(2)

      if uncollectable['is_card_declined?']
        reason = 'card declined'
      else if uncollectable['is_card_expired?']
        reason = 'card expired'
      else
        reason = 'charge fail'

      row =
        `<tr>
          <td>{date}</td>
          <td className="capitalize">{paymentMethod}</td>
          <td>{uncollectable.description}</td>
          <td className="capitalize">{reason}</td>
          <td>{displayAmount}</td>
        </tr>`
      uncollectables.push(row)

    if uncollectables.length > 0
      uncollectableTable = `
      <div className="uncollectables">
        <div className="uncollectable-msg">You have unpaid lessons, which are listed immediately below. <a onClick={this.selectionMade.bind(this, this.TILE_PAYMENT_METHOD)}>Click here</a> to update your credit card info.</div>
        <div className="table-header">Unpaid Lessons</div>
        <table className="payment-table unpaid">
          <thead>
          <tr>
            <th>CHARGED AT</th>
            <th>DESCRIPTION</th>
            <th>REASON</th>
            <th>AMOUNT</th>
          </tr>
          </thead>
          <tbody>
          {uncollectables}
          </tbody>
        </table>
        <div className="table-header second">Payments</div>
      </div>`
    for paymentHistory in @getCurrentList()
      paymentMethod = 'Credit Card'
      if paymentHistory.sale?
        sale = paymentHistory.sale
        amt = sale.recurly_total_in_cents
        status = 'paid'
        displayAmount = ' $' + (amt/100).toFixed(2)
        date = context.JK.formatDate(sale.created_at, true)
        items = []
        for line_item in sale.line_items
          items.push(line_item.product_info?.name)
        description = items.join(', ')
      else
        # this is a recurly webhook
        #transaction = paymentHistory.transaction
        #amt = transaction.amount_in_cents
        #status = transaction.transaction_type
        #displayAmount = '($' + (amt/100).toFixed(2) + ')'
        #date = context.JK.formatDate(transaction.transaction_at, true)
        #description = transaction.admin_description
        invoice = paymentHistory
        amt = invoice.total_in_cents
        status = invoice.state
        displayAmount = '($' + (amt/100).toFixed(2) + ')'
        date = context.JK.formatDate(invoice.created_at, true)
        description = invoice.description

      amountClasses = {status: status}

      row =
        `<tr>
          <td>{date}</td>
          <td>{description}</td>
          <td className="capitalize">{status}</td>
          <td className={classNames(amountClasses)}>{displayAmount}</td>
        </tr>`
      rows.push(row)

    `<div>
      {uncollectableTable}
      <table className="payment-table">
        <thead>
        <tr>
          <th>DATE</th>
          <th>DESCRIPTION</th>
          <th>STATUS</th>
          <th>AMOUNT</th>
        </tr>
        </thead>
        <tbody>
        {rows}
        </tbody>

      </table>
      <a className="btn-next-pager" href="/api/sales?page=1">Next</a>
      <div className="end-of-payments-list end-of-list">No more payment history</div>
      <div className="input-aligner">
        <a className="back button-grey" onClick={this.onBack}>BACK</a>
      </div>
      <br className="clearall" />
    </div>`

  selectionMade: (selection, e) ->
    e.preventDefault()
    #@getUncollectables()
    @setState({selected: selection})

  activeTile: (selected = this.state.selected) ->
    if selected?
      selected
    else
      @tiles()[-1]

  createTileLink: (i, tile) ->
    if this.state.selected?
      active = this.state.selected == tile
    else
      active = i == 0


    tileClasses = {activeTile: active, 'profile-tile': true}
    tileClasses[@myRole()] = true
    tileClasses = classNames(tileClasses)

    classes = classNames({last: i == @tiles().length - 1})

    return `<div key={i} className={tileClasses}><a className={classes}
                                                     onClick={this.selectionMade.bind(this, tile)}>{tile}</a></div>`

  tiles: () ->
    #if @viewerStudent()
    #  tiles = @STUDENT_TILES
    #else
    #  tiles = @TEACHER_TILES
    #tiles
    @STUDENT_TILES

  myRole: () ->
    if @viewerStudent()
      'student'
    else
      'teacher'

  viewerStudent: () ->
    #!@viewerTeacher()
    true

  viewerTeacher: () ->
    this.state.user?.is_a_teacher

  onCustomBack: (customBack, e) ->
    e.preventDefault()
    context.location = customBack

  render: () ->
    mainContent = @mainContent()

    profileSelections = []
    for tile, i in @tiles()
      profileSelections.push(@createTileLink(i, tile, profileSelections))

    profileNavClasses = {"profile-nav": true}
    profileNavClasses[@myRole()] = true
    profileNavClasses = classNames(profileNavClasses)
    profileNav = `<div className={classNames(profileNavClasses)}>
      {profileSelections}
    </div>`

    `<div className="content-body-scroller">
      <div className="profile-header profile-head">
        <div className="account-header">payment<br/>management:</div>
        {profileNav}
        <div className="clearall"></div>
      </div>

      <div className="profile-body">
        <div className="profile-wrapper">
          <div className="main-content">
            {mainContent}
            <br />
          </div>
        </div>
      </div>
    </div>`

  onUpdate: (e) ->
    e.preventDefault()

    if this.state.updating
      return
    name = @root.find('input[name="name"]').val()
    if @isSchoolManaged()
      scheduling_communication = 'school'
    else
      scheduling_communication = 'teacher'
    correspondence_email = @root.find('input[name="correspondence_email"]').val()

    @setState({updating: true})
    rest.updateSchool({
      id: this.state.school.id,
      name: name,
      scheduling_communication: scheduling_communication,
      correspondence_email: correspondence_email
    }).done((response) => @onUpdateDone(response)).fail((jqXHR) => @onUpdateFail(jqXHR))

  onUpdateDone: (response) ->
    @setState({school: response, userSchedulingComm: null, schoolName: null, updateErrors: null, updating: false})

    @app.layout.notify({title: "update success", text: "Your school information has been successfully updated"})

  onSubmitForm: (e) ->
    form = document.querySelector('#user-payment-submit')
    e.preventDefault()
    @onSubmit(form)

  onSubmit: (form) ->
    @resetErrors()
    #e.preventDefault()
    console.log("onSubmit")
    if !window.recurly?
      @app.layout.notify({
        title: 'Payment System Not Loaded',
        text: "Please refresh this page and try to enter your info again. Sorry for the inconvenience!"
      })
    else
      errored = false
      # do a client-side sweep 1st
      if !@root.find('input.first_name').val()
        errored = true
        @setState({firstNameError: true})
      if !@root.find('input.last_name').val()
        errored = true
        @setState({lastNameError: true})
      if !@root.find('input.address-1').val()
        errored = true
        @setState({address1Error: true})
      if !@root.find('input.city').val()
        errored = true
        @setState({cityError: true})
      if !@root.find('input.state').val()
        errored = true
        @setState({stateError: true})
      if !@root.find('select.country').val()
        errored = true
        @setState({countryError: true})
      if !@root.find('input.zip').val()
        errored = true
        @setState({zipCodeError: true})

      if errored
        return

      #form = event.target
      @setState({updating: true})
      window.recurly.token(@elements, form, @onRecurlyToken)

  onUpdateFail: (jqXHR) ->
    handled = false

    @setState({updating: false})

    if jqXHR.status == 422
      errors = JSON.parse(jqXHR.responseText)
      handled = true
      @setState({updateErrors: errors})
    else
      console.log("error path not taken", jqXHR)

  onSubmitOld: (e) ->
    @resetErrors()

    e.preventDefault()

    if !window.Stripe?
      @app.layout.notify({
        title: 'Payment System Not Loaded',
        text: "Please refresh this page and try to enter your info again. Sorry for the inconvenience!"
      })
    else
      ccNumber = @root.find('input.card-number').val()
      expiration = @root.find('input.expiration').val()
      cvv = @root.find('input.cvv').val()
      inUS = @root.find('input.billing-address-in-us').is(':checked')
      zip = @root.find('input.zip').val()

      error = false

      if @state.shouldShowName
        name = @root.find('#set-user-on-card').val()

        if name.indexOf('Anonymous') > -1
          @setState({nameError: true})
          error = true

      if !$.payment.validateCardNumber(ccNumber)
        @setState({ccError: true})
        error = true

      bits = expiration.split('/')

      if bits.length == 2
        month = bits[0].trim()
        year = bits[1].trim()

        month = new Number(month)
        year = new Number(year)

        if year < 2000
          year += 2000

        if !$.payment.validateCardExpiry(month, year)
          @setState({expiryError: true})
          error = true
      else
        @setState({expiryError: true})
        error = true


      cardType = $.payment.cardType(ccNumber)

      if !$.payment.validateCardCVC(cvv, cardType)
        @setState({cvvError: true})
        error = true

      if inUS && (!zip? || zip == '')
        @setState({zipCodeError: true})

      if error
        return

      data = {
        number: ccNumber,
        cvc: cvv,
        exp_month: month,
        exp_year: year,
      }

      @setState({updating: true})

      window.Stripe.card.createToken(data, (status, response) => (@stripeResponseHandler(status, response)));

  stripeResponseHandler: (status, response) ->
    console.log("stripe response", JSON.stringify(response))


    if response.error
      @setState({updating: false})
      if response.error.code == "invalid_number"
        @setState({ccError: true, cvvError: null, expiryError: null})
      else if response.error.code == "invalid_cvc"
        @setState({ccError: null, cvvError: true, expiryError: null})
      else if response.error.code == "invalid_expiry_year" || response.error.code == "invalid_expiry_month"
        @setState({ccError: null, cvvError: null, expiryError: true})

    #@setState({userWantsUpdateCC: false})
    #window.UserActions.refresh()
    @storeCC(response.id)

  storeCC: (token) ->
    if this.state.billingInUS
      zip = @root.find('input.zip').val()

    data = {
      token: token,
      zip: zip,
      test_drive: false,
      normal: false
    }

    if @state.shouldShowName
      data.name = @root.find('#set-user-on-card').val()

    @setState({updating: true})
    rest.submitStripe(data).done((response) => @stripeSubmitted(response)).fail((jqXHR) => @stripeSubmitFailure(jqXHR))

  stripeSubmitted: (response) ->
    @setState({updating: false})

    logger.debug("stripe submitted: " + JSON.stringify(response))

    @setState({userWantsUpdateCC: false})

    #if @state.shouldShowName
    window.UserActions.refresh()

    if response.past_due
      context.JK.Banner.showAlert('Credit Card Updated', 'Thank you. Your credit card info has been updated.<br/><br/>We will try to bill any unpaid lessons within the next hour, and an email will be sent at that time.')
    else
      @app.layout.notify({title: 'Credit Card Updated', text: 'Your credit card info has been updated.'})


  stripeSubmitFailure: (jqXHR) ->
    @setState({updating: false})
    handled = false
    if jqXHR.status == 422
      errors = JSON.parse(jqXHR.responseText)
      if errors.errors.name?
        @setState({name: errors.errors.name[0]})
        handled = true
      else if errors.errors.user?
        @app.layout.notify({title: "Can't Update Credit Card", text: "You " + errors.errors.user[0] + '.' })
        handled = true

    if !handled
      @app.notifyServerError(jqXHR, 'Credit Card Not Stored')

  onUnlockPaymentInfo: (e) ->
    e.preventDefault()
    @setState({userWantsUpdateCC: true})

  onLockPaymentInfo: (e) ->
    e.preventDefault()
    @setState({userWantsUpdateCC: false})

  reuseStoredCard: () ->
    !@state.userWantsUpdateCC && @state.user?['has_stored_credit_card?'] && @state.uncollectables.length == 0

})