require 'twilio-ruby'

class Attempt < ApplicationRecord

  belongs_to :schedule
  belongs_to :recipient
  belongs_to :recipient_schedule
  belongs_to :question
  belongs_to :student

  after_save :update_school_categories
  after_commit :update_counts

  scope :for_question, -> (question) { where(question_id: question.id) }
  scope :for_recipient, -> (recipient) { where(recipient_id: recipient.id) }
  scope :for_student, -> (student) { where(student_id: student.id) }
  scope :for_category, -> (category) { joins(:question).merge(Question.for_category(category)) }
  scope :for_school, -> (school) { joins(:recipient).merge(Recipient.for_school(school)) }
  scope :with_answer, -> { where('answer_index is not null or open_response_id is not null')}
  scope :with_no_answer, -> { where('answer_index is null and open_response_id is null')}
  scope :not_yet_responded, -> { where(responded_at: nil) }
  scope :last_sent, -> { order(sent_at: :desc) }
  scope :created_in, -> (year) { where('extract(year from attempts.created_at) = ?', year) }

  def messages
    child_specific = student.present? ? " (for #{student.name})" : ''

    cancel_text = "\nSkip question: skip\nStop all questions: stop"

    [
      "#{question.text}#{child_specific}",
      "#{question.option1}: Reply 1\n#{question.option2}: 2\n#{question.option3}: 3\n#{question.option4}: 4\n#{question.option5}: 5"
    ]
  end

  def send_message
    twilio_number = ENV['TWILIO_NUMBER']
    client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']

    sids = []
    messages.each do |message|
      sids << client.messages.create(
        from: twilio_number,
        to:   recipient.phone,
        body: message
      ).sid
    end

    update(sent_at: Time.new, twilio_sid: sids.join(','))
    recipient.update(phone: client.messages.get(sids.last).to)
  end

  def response
    return 'No Answer Yet' if answer_index.blank?
    question.options[answer_index_with_reverse - 1]
  end

  def save_response(answer_index: nil, twilio_details: nil, responded_at: Time.new)
    update(
      answer_index: answer_index,
      twilio_details: twilio_details,
      responded_at: responded_at
    )

    if recipient_schedule.queued_question_ids.present?
      recipient_schedule.update(next_attempt_at: Time.new)
    end
  end

  def answer_index_with_reverse
    return 6 - answer_index if question.reverse?
    return answer_index
  end

  private

    def update_school_categories
      return if ENV['BULK_PROCESS']
      school_category = SchoolCategory.for(recipient.school, question.category).first
      if school_category.nil?
        school_category = SchoolCategory.create(school: recipient.school, category: question.category)
      end
      school_category.sync_aggregated_responses
    end

    def update_counts
      return if ENV['BULK_PROCESS']
      recipient.update_counts
    end

end
