# frozen_string_literal: true

class User < ActiveRecord::Base
  include RememberMe::Model
  include PgSearch

  has_many :account_auths, dependent: :destroy
  has_many :accounts, through: :account_auths
  has_many :project_memberships, dependent: :destroy

  has_one_attached :avatar

  has_secure_token :password_reset_token

  validates :email, presence: true, uniqueness: true
  validates :password_digest, presence: true
  validates :time_zone, presence: true

  scope :order_by_email, -> { order(email: :asc) }

  attr_accessor :interested_product_name

  def primary_account
    accounts.first
  end

  def primary_account=(account)
    accounts << account
  end

  def associate?(account)
    account_membership_for(account).associate?
  end

  def manager?(account)
    account_membership_for(account).project_manager?
  end

  def account_manager?(account)
    account_membership_for(account).account_manager?
  end

  def role_for(account)
    account_membership_for(account).role
  end

  def accessible_projects_for(account)
    if account_manager?(account)
      Project.joins(account: :account_auths).where(account_auths: { user_id: self })
    else
      Project.joins(project_memberships: :project).where(projects: { account_id: account }, project_memberships: { user_id: self })
    end
  end

  def full_name
    "#{first_name} #{last_name}".titleize
  end

  # needed for knock jwt authentication
  def authenticate(cleartext_password)
    Oath.compare_token(password_digest, cleartext_password) ? self : false
  end

  def anonymous?
    false
  end

  private

  def account_membership_for(account)
    account_auths.find_by!(account: account)
  end

  def self.searchable_on(fields)
    search_opts = {
      against: fields,
      using: {
        tsearch: { any_word: true, prefix: true },
        trigram: {},
        dmetaphone: { any_word: true }
      }
    }

    send(:pg_search_scope, :search, search_opts)
  end

  searchable_on %i[first_name last_name email]
end
