# Manually (or otherwise) update a person from trogdir (or via a hash if you're
#  feeling plucky)
class UpdatePersonFromTrogdir

  attr_reader :trogdir_id, :trogdir_person, :person

  # This will look a person up in trogdir via their uuid and will update everything
  #  that doesn't match
  # @param trogdir_id [String] The trogdir equivalent of the uuid
  # @param trogdir_person [hash] The trogdir manually rendered hash of the persons attrs
  # @return [true]
  # @note Any of the attributes that are missing from the hash will be saved as nil.
  def initialize(trogdir_id:, trogdir_person: nil)
    @trogdir_id = trogdir_id
    @trogdir_person = OpenStruct.new(trogdir_person || load_trogdir_person_from_api)
    @person = Person.find_by(trogdir_id: trogdir_id)
  end

  def update!
    person.assign_attributes(
      first_name: trogdir_person.first_name,
      preferred_name: trogdir_person.preferred_name,
      middle_name: trogdir_person.middle_name,
      last_name: trogdir_person.last_name,
      display_name: trogdir_person.display_name,
      gender: trogdir_person.gender,
      birth_date: trogdir_person.birth_date,
      department: trogdir_person.department,
      affiliations: trogdir_person.affiliations,
      mailbox: trogdir_person.mailbox,
      majors: trogdir_person.majors,
      minors: trogdir_person.minors,
      privacy: trogdir_person.privacy,
      biola_title: trogdir_person.title,
      biola_id: get_element('ids', 'biola_id', 'identifier'),
      biola_email: get_element('emails', 'university', 'address'),
      employee_phone: get_element('phones', 'office', 'number'),
      personal_phone: get_element('phones', 'cell', 'number'),
      biola_photo_url: get_element('photos', 'id_card', 'url')
    )

    if person.department != trogdir_person.department
      leave_department! person.department if person.department.present?
      join_department! trogdir_person.department
    end

    person.save!
  end

  private
  def trogdir_people
    Trogdir::APIClient::People.new
  end

  def load_trogdir_person_from_api
    trogdir_people.show(uuid: trogdir_id).perform.parse.with_indifferent_access
  end

  #
  # Gets nested elements from trogdir_person hash, if they are available.
  #
  def get_element(objects, type, method)
    (trogdir_person.send(objects).find{|obj| obj['type'] == type} || {})[method]
  end

  #
  # Leave the department if it exists
  #
  def leave_department!(department_name)
    if department_name.present? && dept = Department.where(hr_title: department_name).first
      dept.memberships.where(person: person).destroy_all
    end
  end

  #
  # Join the department if it exists
  #
  def join_department!(department_name)
    if department_name.present? && dept = Department.where(hr_title: department_name).first
      dept.memberships.create(person: person)
    end
  end
end
