class MobileAppApi::V1::SessionController < MobileAppApi::V1::BaseController
  before_filter :login_required!
  before_filter :find_tutored_session, only: [:add_review, :pay_for_session, :edit_review]

  # Method to get tutoring session details based on session Id.
  def get_session_details
    session = @user.related_sessions.find(params[:session_id])
    if !session.nil?
      render json: { status: 200,
        session_details: session.as_mobile_api,
        service_provider: session.tutor,
        consumer: session.user}
    else
      render json: { status: 400, error: "Session with id #{params[:session_id]} not found." }
    end
  end

  # Method to accept tutoring session by tutor.
  def accept_session
    tutoring_session = @user.tutoring_sessions.find(params[:session_id])
    unless tutoring_session.confirmed?
      unless tutoring_session.confirm!(params[:message])
        render json: { status: 400, error: "Can't confirm session. Cannot charge card." }
      end
      TutoringSessionsMailer.delay(queue: :mailer).confirmed_email_student(tutoring_session.id)
      render json: { status: 200, success: "Session confirmed." }
    else
      render json: { status: 400, error: "This session has already been confirmed by you." }
    end
  end


  # Method to accept tutoring session by tutor.
  def reject_session
    tutoring_session = @user.tutoring_sessions.find(params[:session_id])
    unless tutoring_session.rejected?
      if tutoring_session.reject!(params[:message] , @user)
        render json: {status: 200, success: "Session rejected." }
      else
        render json: {status: 400, error: "Can't reject session" }
      end
    else
      render json: {status: 400, error: "Can't reject session - This session is already rejected." }
    end
  end

  # Used to add review by user for tutoring sessions.
  def add_review
    if save_review
      render json: { status: 200, review_id: @review.id, success: "Review created for #{@tutoring_session.tutor.name} by #{@user.name}" }
    else
      render json: { status: 400, error: @review.errors.full_messages }
    end
  end


  # Find and Update review added by user.
  def edit_review
    tutor = Tutor.find_by(id: params[:review][:for_user_id])
    review = @user.reviews_posted.find_by(params[:review][:id])
    params[:review].delete(:course_id) if params[:review][:course_id].present? #Course cannot be changed while updating review
    avg = Review.calc_average params[:review]
    params[:review][:average_review] = avg
    if review.update_attributes review_params
      render json: { status: 200, success: "Review updated for #{tutor.name} by #{@user.name}" }
    else
      render json: { status: 400, error: review.errors.full_messages }
    end
  end

  # Get review details by its Id.
  def get_review_details
    if @user.student?
      review = @user.reviews_posted.find params[:review_id]
    else
      review = @user.reviews_received.find params[:review_id]
    end
    render json: { status: 200, review: JSON.parse(review.to_json) }
  end

  # Method to book tutoring session by user.
  def book_session
    tutor = Tutor.find(params[:tutor_id])
    params[:tutoring_session][:start] = params[:tutoring_session].delete(:start_time)
    params[:tutoring_session][:end_time]= ((params[:tutoring_session][:start]).to_time+((params[:tutoring_session][:end_time]).to_i*60)).hr_min
    params[:tutoring_session][:end] = params[:tutoring_session].delete(:end_time)
    tutoring_session = tutor.tutoring_sessions.new tutoring_session_params
    tutoring_session.user = @user
    if @user.has_credit_card?
      if tutoring_session.save
        TutoringSessionsMailer.create_email(tutoring_session).deliver
        render json: { status: 200, session_details: tutoring_session }
      else
        render json: { status: 400, error: tutoring_session.errors.messages }
      end
    else
      render json: {status: 400, error: "Consumer has no credit card information"}
    end
  end

  # Method to reschedule the tutoring session i.e. updating date and time for sessions.
  def reschedule_session
    params[:tutoring_session][:start] = params[:tutoring_session].delete(:start_time)
    params[:tutoring_session][:end] = params[:tutoring_session].delete(:end_time)
    tutoring_session = @user.tutored_sessions.find(params[:session_id])
    if tutoring_session.pending?
      if tutoring_session.update_attributes(tutoring_session_params)
        tutoring_session.send_tutoring_session_update_mail
        render json: {success: 200, session_details: tutoring_session}
      else
        render json: {status: 400, error: "Rescheduling failed.",error_details: tutoring_session.errors.full_messages}
      end
    else
      render json: {status: 400, error: "Can't reschedule non-pending sessions."}
    end

  end

  # Get Invoice of session by its session Id.
  def get_invoice_by_session
    invoice = @user.related_invoices.find_by(invoiceable_id: params[:session_id])
    if invoice
      render json: {status: 200, invoice_details: invoice.as_mobile_api}
    else
      render json: {status: 400, error: "No invoice found for session_id #{params[:session_id]}."}
    end
  end

  # Get all invoices for current user.
  def get_all_invoices
    invoices = @user.related_invoices
    if invoices
      render json: {status: 200, invoices: invoices.map(&:as_mobile_api)}
    else
      render json: { status: 400, error: "User with auth_token #{params[:auth_token]} not found." }
    end
  end

  # Method to create invoice for tutoring session and pay to tutor by student.
  def pay_for_session
    @invoice = @tutoring_session.find_or_create_invoice!
    unless @invoice.paid?
      confirm_session_for_manually_billed_invoice!
      if @invoice.pay_tutor
        if review = save_review
          render json: {status: 200, invoice: @invoice.as_mobile_api, review: review, success: "Tutor is paid for session with id #{params[:session_id]}."}
        else
          render json: {status: 200, invoice: @invoice.as_mobile_api, success: "Tutor is paid for session with id #{params[:session_id]}."}
        end
      else
        if @invoice.manually_billed?
          message = "Your amount for this invoice has been transfered to #{Configurations::General.application_name} escrow account. But unable to make payment to the #{Tutor.model_name.human}. Please contact #{Configurations::General.application_name} team."
        else
          message = "Unable to make payment to #{Tutor.model_name.human}. Please contact #{Configurations::General.application_name} team."
        end
        render json: {status: 400, error: message}
      end
    else
      render json: {status: 400, error: "Session with id #{params[:session_id]} has already been paid"}
    end
  end

  private

  def tutoring_session_params
    params.required(:tutoring_session).permit(:start, :end, :date, :category_id, :subject_id, :on_site, :location, :course_id, :resource_id, :resource_type)
  end

  def review_params
    params.required(:review).permit(:helpfulness, :timeliness, :knowledge, :friendliness).merge(user: @user, for_user: @tutoring_session.tutor)
  end

  def find_tutored_session
    @tutoring_session = @user.tutored_sessions.find(params[:session_id])
  end

  def save_review
    @review = @tutoring_session.review || @tutoring_session.build_review
    @review.attributes = review_params
    @review.save
  end

  def confirm_session_for_manually_billed_invoice!
    if @invoice.manually_billed? and !@tutoring_session.confirmed?
      if Charge.charge_for @tutoring_session
        @tutoring_session.confirm!
      else
        render json: {status: 400, error: "Unable to charge your card. Please contact #{Configurations::General.application_name} team."} and return
      end
    end
  end

end
