=begin
require 'spec_helper'

describe "Recurring Lesson Flow" do

  let(:user) { FactoryGirl.create(:user, remaining_test_drives: 0) }

  let(:teacher_user) { FactoryGirl.create(:teacher_user) }
  let(:teacher) { teacher_user.teacher }
  let(:lesson_booking_slot_single1) { FactoryGirl.build(:lesson_booking_slot_single) }
  let(:lesson_booking_slot_single2) { FactoryGirl.build(:lesson_booking_slot_single) }
  let(:lesson_booking_slot_recurring1) { FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 2.days.from_now.wday) }
  let(:lesson_booking_slot_recurring2) { FactoryGirl.build(:lesson_booking_slot_recurring, day_of_week: 3.days.from_now.wday) }
  let(:valid_single_slots) { [lesson_booking_slot_single1, lesson_booking_slot_single2] }
  let(:valid_recurring_slots) { [lesson_booking_slot_recurring1, lesson_booking_slot_recurring2] }

  after(:each) do
    Timecop.return
  end
  it "works" do

    # user has no test drives, no credit card on file, but attempts to book a lesson
    booking = LessonBooking.book_normal(user, teacher_user, valid_recurring_slots, "Hey I've heard of you before.", true, LessonBooking::PAYMENT_STYLE_SINGLE, 60)
    booking.errors.any?.should be_false
    booking.card_presumed_ok.should be_false
    booking.user.should eql user
    booking.card_presumed_ok.should be_false
    booking.should eql user.unprocessed_normal_lesson
    booking.sent_notices.should be_false
    booking.booked_price.should eql 30.00

    ##########  Need validate their credit card
    token = create_stripe_token
    result = user.payment_update({token: token, zip: '78759', normal: true, booking_id: booking.id})
    booking = result[:lesson]
    lesson = booking.lesson_sessions[0]
    booking.errors.any?.should be_false
    lesson.errors.any?.should be_false
    booking.card_presumed_ok.should be_true
    booking.sent_notices.should be_true
    lesson.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
    lesson.amount_charged.should be 0.0
    lesson.reload

    user.reload
    user.stripe_customer_id.should_not be nil
    user.remaining_test_drives.should eql 0
    user.lesson_purchases.length.should eql 0

    customer = Stripe::Customer.retrieve(user.stripe_customer_id)
    customer.email.should eql user.email

    booking.lesson_sessions.length.should eql 1
    lesson_session1 = booking.lesson_sessions[0]
    lesson_session1.status.should eql LessonBooking::STATUS_REQUESTED
    booking.status.should eql LessonBooking::STATUS_REQUESTED

    ######### Teacher counters with new slot
    teacher_countered_slot = FactoryGirl.build(:lesson_booking_slot_recurring, hour: 14, update_all: true)
    UserMailer.deliveries.clear
    booking.counter_slot.should be_nil
    lesson_session1.counter({proposer: teacher_user, slot: teacher_countered_slot, message: 'Does this work?'})
    booking.reload
    booking.errors.any?.should be false
    lesson_session1.lesson_booking.errors.any?.should be false
    booking.lesson_booking_slots.length.should eql 3
    #booking.lesson_booking_slots[2].proposer.should eql teacher_user
    teacher_counter = booking.counter_slot
    teacher_counter.should eql teacher_countered_slot
    teacher_counter.proposer.should eql teacher_user
    booking.lesson_booking_slots.length.should eql 3
    UserMailer.deliveries.length.should eql 1
    chat = ChatMessage.unscoped.order(:created_at).last
    chat.channel.should eql ChatMessage::CHANNEL_LESSON
    chat.message.should eql 'Does this work?'
    chat.user.should eql teacher_user
    chat.target_user.should eql user
    notification = Notification.unscoped.order(:created_at).last
    notification.session_id.should eql lesson_session1.music_session.id
    notification.student_directed.should eql true
    notification.purpose.should eql 'counter'
    notification.description.should eql NotificationTypes::LESSON_MESSAGE
    #notification.message.should eql "Instructor has proposed a different time for your lesson."

    ######### Student counters with new slot
    student_countered_slot = FactoryGirl.build(:lesson_booking_slot_recurring, hour: 16, update_all: true, day_of_week: 2.days.from_now.wday)
    UserMailer.deliveries.clear
    lesson_session1.counter({proposer: user, slot: student_countered_slot, message: 'Does this work better?'})
    lesson_session1.errors.any?.should be false
    lesson_session1.lesson_booking.errors.any?.should be false
    lesson_session1.lesson_booking_slots.length.should eql 2
    lesson_session1.slot.is_recurring?.should be true
    student_counter = booking.lesson_booking_slots.order(:created_at).last
    student_counter.proposer.should eql user
    booking.reload
    booking.lesson_booking_slots.length.should eql 4
    UserMailer.deliveries.length.should eql 1
    chat = ChatMessage.unscoped.order(:created_at).last
    chat.message.should eql 'Does this work better?'
    chat.channel.should eql ChatMessage::CHANNEL_LESSON
    chat.user.should eql user
    chat.target_user.should eql teacher_user
    notification = Notification.unscoped.order(:created_at).last
    notification.session_id.should eql lesson_session1.music_session.id
    notification.student_directed.should eql false
    notification.purpose.should eql 'counter'
    notification.description.should eql NotificationTypes::LESSON_MESSAGE

    ######## Teacher accepts slot
    UserMailer.deliveries.clear
    lesson_session1.accept({message: 'Yeah I got this', slot: student_counter.id, accepter: teacher_user})
    UserMailer.deliveries.each do |del|
      #puts del.subject
    end
    # get acceptance emails, as well as 'your stuff is accepted'
    UserMailer.deliveries.length.should eql 2
    lesson_session1.errors.any?.should be_false
    lesson_session1.reload
    lesson_session1.slot.should eql student_counter
    lesson_session2 = booking.lesson_sessions.order(:created_at).last
    booking.reload
    booking.counter_slot.should be_nil
    lesson_session1.status.should eql LessonSession::STATUS_APPROVED
    lesson_session2.status.should eql LessonSession::STATUS_APPROVED
    booking.reload
    booking.default_slot.should eql student_counter
    lesson_session1.music_session.scheduled_start.should eql booking.default_slot.scheduled_time(0)
    booking.status.should eql LessonBooking::STATUS_APPROVED

    UserMailer.deliveries.length.should eql 2
    chat = ChatMessage.unscoped.order(:created_at).last
    chat.message.should eql "Yeah I got this"
    chat.purpose.should eql 'Lesson Approved'
    chat.channel.should eql ChatMessage::CHANNEL_LESSON
    chat.user.should eql teacher_user
    chat.target_user.should eql user
    notification = Notification.unscoped.order(:created_at).last
    notification.session_id.should eql lesson_session1.music_session.id
    notification.student_directed.should eql true
    notification.purpose.should eql 'accept'
    notification.description.should eql NotificationTypes::LESSON_MESSAGE
    user.reload
    user.sales.length.should eql 0

    booking.reload
    booking.lesson_sessions[0].scheduled_start.should_not eql booking.lesson_sessions[1].scheduled_start

    # teacher & student get into session
    start = lesson_session1.scheduled_start
    end_time = lesson_session1.scheduled_start + (60 * lesson_session1.duration)
    uh2 = FactoryGirl.create(:music_session_user_history, user: teacher_user, history: lesson_session1.music_session, created_at: start, session_removed_at: end_time)
    # artificially end the session, which is covered by other background jobs
    lesson_session1.music_session.session_removed_at = end_time
    lesson_session1.music_session.save!

    Timecop.travel(end_time + 1)

    UserMailer.deliveries.clear
    # background code comes around and analyses the session
    LessonSession.hourly_check
    lesson_session1.reload
    lesson_session1.analysed.should be_true
    analysis = lesson_session1.analysis
    analysis["reason"].should eql LessonSessionAnalyser::STUDENT_FAULT
    analysis["student"].should eql LessonSessionAnalyser::NO_SHOW
    if lesson_session1.billing_error_detail
      puts "testdrive flow #{lesson_session1.billing_error_detail}" # this should not occur, but helps a great deal if a regression occurs and running all the tests
    end
    lesson_session1.billed.should be true
    user.reload
    user.lesson_purchases.length.should eql 1
    lesson_purchase = user.lesson_purchases[0]
    lesson_purchase.price.should eql 30.00
    lesson_purchase.lesson_package_type.is_normal?.should eql true
    lesson_purchase.price_in_cents.should eql 3000
    user.sales.length.should eql 1
    sale = user.sales.first
    sale.stripe_charge_id.should_not be_nil
    sale.recurly_tax_in_cents.should eql (100 * booking.booked_price.to_f * 0.0825).round.to_i
    sale.recurly_total_in_cents.should eql ((100 * booking.booked_price.to_f * 0.0825).round + 100 * booking.booked_price.to_f).to_i
    sale.recurly_subtotal_in_cents.should eql (100 * booking.booked_price).to_i
    sale.recurly_currency.should eql 'USD'
    sale.stripe_charge_id.should_not be_nil
    line_item = sale.sale_line_items[0]
    line_item.quantity.should eql 1
    line_item.product_type.should eql SaleLineItem::LESSON
    line_item.product_id.should eq LessonPackageType.single.id
    line_item.lesson_package_purchase.should eql lesson_purchase
    lesson_purchase.sale_line_item.should eql line_item
    lesson.amount_charged.should eql (sale.recurly_total_in_cents / 100.0).to_f
    lesson_session1.billing_error_reason.should be_nil
    lesson_session1.sent_billing_notices.should be true
    user.reload
    user.remaining_test_drives.should eql 0
    UserMailer.deliveries.each do |d|
      puts d.subject
    end
    UserMailer.deliveries.length.should eql 2 # one for student, one for teacher
  end
end
=end