require 'httparty'
require 'sinatra/activerecord'
require 'twilio-ruby'

class User < ActiveRecord::Base
  store_accessor :preintervention_responses
  store_accessor :postintervention_responses

  #phony_normalize :phone_number, :default_country_code => 'US'

  validates_uniqueness_of :short_code
  validates_uniqueness_of :email, allow_nil: true, allow_blank: true

  before_create  :ensure_token
  after_save     :send_guardian_email, if: lambda { |user| !user.guardian_email.nil? && guardian_email_sent.nil? }
  after_save     :schedule_baseline_reminder, if: lambda{ |user| !user.baseline_reminder_scheduled && user.eligible? }

  def eligible?
    #TODO: Check for language
    if (country == "US" && !language.nil? && language != "other" && (13..18).include?(age))
      true
    else
      false
    end
  end

  def ensure_token
    if token.blank?
      self.token = generate_token
    end
  end

  def baseline_survey_completed?
    if intervention_started
      true
    else
      false
    end
  end

  def schedule_baseline_reminder
    if !baseline_reminder_scheduled
      BaselineReminderWorker.perform_in(24.hours, self.id)
      self.update_attribute(:baseline_reminder_scheduled, true)
    end
  end

  def postintervention_started?
    !postintervention_responses.nil? && !postintervention_responses.empty?
  end

  def postintervention_completed?
    !postintervention_completed.nil?
  end

  def next_page_route
    preintervention = true if !postintervention_started?

    if next_page.nil?
      if consent_given != true
        show_assent_form? ? "/assent" : "/consent"
      else
        "/survey/1"
      end
    elsif baseline_survey_completed? && preintervention
      #first page of postintervention
     "/postintervention/1"
    elsif next_page == "confirmation"
      if preintervention
        #go to postintervention start
        "/postintervention/1"
      else
        "/postintervention/confirmation"
      end
    else
      if preintervention
        "/survey/#{next_page}"
      else
        "/postintervention/#{next_page}"
      end
    end
  end

  def send_guardian_email
    GuardianMailer.delay.send(guardian_email)
    self.guardian_email_sent = Time.now
    self.save
  end

  def send_postintervention_email
    if self.email
      PostinterventionMailer.delay.send(self.email, self.token)
      self.postintervention_email_sent = Time.now
      self.save
    else
      puts "Could not send postintervention email to participant #{u.id}: no email address given"
    end
  end

  def send_sms_short_code
    if eligible?
      if short_code.nil?
        code = generate_short_code
        self.update_attribute(:short_code, code)
      end

      send_text "Hi from Text to Connect! Your short code is #{short_code}"
    end
  end

  def send_text(message)
    unless phone_number.nil?
      client = Twilio::REST::Client.new(ENV['TWILIO_SID'], ENV['TWILIO_AUTH_TOKEN'])

      client.account.messages.create(
        from: ENV['TWILIO_PHONE_NUMBER'],
        to:   phone_number,
        body: message
      )
    end
  end

  def show_assent_form?
    age < 15
  end

  def start_intervention
    if intervention_started.nil?
      base = ENV['HOPELAB_ENGINE_URL']
      url = "#{base}/new_subject"

      started = HTTParty.post(url, body: { phone_number: phone_number, start: preferred_time, name: token, timezone: timezone })

      if started.response.code == "200"
        update_attribute(:intervention_started, Time.now)
        PostinterventionReminderWorker.perform_in(16.days, self.id)
        PostinterventionEmailWorker.perform_in(15.days, self.id)
      end
    end
  end


  private

  def generate_short_code
    code = SecureRandom.hex(4)
    if User.where(:short_code => code)
      return code
    else
      generate_short_code
    end
  end

  def generate_token
    loop do
      token = SecureRandom.urlsafe_base64(10)
      break token unless User.where(token: token).first
    end
  end
end
