# frozen_string_literal: true
class Candidate < ApplicationRecord
  belongs_to :quiz
  has_many :questions, -> { order("sort") }, through: :quiz
  has_many :answers
  belongs_to :recruiter, class_name: "User"
  has_many :votes, class_name: "ReviewerVote"
  has_many :reviewers, through: :quiz
  has_many :quiz_comments, foreign_key: :test_hash, primary_key: :test_hash

  serialize :email, CryptSerializer

  before_validation(:generate_test_hash, on: :create)

  validates :recruiter_id, presence: true
  validates :name, presence: true
  validates :experience, presence: true
  validates :project, presence: true
  validates :position, presence: true
  validates :email, uniqueness: true, presence: true, email_format: true
  validates :test_hash, uniqueness: true, presence: true

  enum review_status: {
    pending: 0,
    approved: 1,
    declined: 2
  }

  def interview?
    return 'yes' if approved?
    'no' if declined?
  end

  def build_reviews
    reviewers.each do |reviewer|
      votes.find_or_create_by(user_id: reviewer.id)
    end
  end

  def manager
    manager_votes = votes.joins(:user).where("users.role = 'manager'")
    return User.new(name: "No Manager") if manager_votes.empty?

    manager_votes.first.user
  end

  def submitted_answers
    answers.where(submitted: true)
  end

  def last_answered_at
    return Time.current unless submitted_answers.count.positive?
    submitted_answers.order(updated_at: :desc).first.updated_at
  end

  def stale?
    return true unless answers.count.positive?
    minutes_since_answered = (Time.current.minus_with_coercion(last_answered_at) / 60).round
    minutes_since_answered > 45
  end

  def answered_questions
    answers.where.not(answer: nil)
           .where("answers.answer not like '%later:%'")
  end

  def fetch_question qid
    CandidateQuiz.new(id).fetch_question(qid)
  end

  def my_quiz
    @candidate_quiz ||= CandidateQuiz.new(id).build_my_quiz
  end

  def my_status
    @candidate_status ||= QuizStatus.new(self)
  end

  def status
    "#{my_status.progress}%"
  end

  private

    def generate_test_hash
      loop do
        self[:test_hash] = SecureRandom.urlsafe_base64(8)

        break unless Candidate.exists?(test_hash: self[:test_hash])
      end
    end
end
