class StudentAdditionalField < ApplicationRecord
  include Base::StudentAdditionalField

  acts_as_list scope: :group, column: :Sequence

  enum type: { text: 1, multi_choice: 2, date: 3 }
  enum validation_type: { nothing: 0, number: 1, email: 2, min_length: 3, max_length: 4, custom: 5 }

  associations_for legacy: true do |a|
    a.belongs_to :school
    a.has_many :student_additional_values, keys: :SSID
  end

  belongs_to :group, class_name: 'StudentAdditionalGroup', foreign_key: :SSGID, inverse_of: :fields

  has_many :choices, class_name: 'StudentAdditionalChoice',
    foreign_key: :SSID, inverse_of: :field, dependent: :destroy

  associations_for namespace: 'Admission' do |a|
    a.has_many :additional_fields, dependent: :destroy
    a.has_many :additional_values, dependent: :restrict_with_error
  end

  accepts_nested_attributes_for :choices, update_only: true, allow_destroy: true

  before_save :remove_choices, unless: :multi_choice?
  after_create :update_rpid

  validates :name, presence: true, length: { maximum: 32 }
  validates :validation_pattern, length: { maximum: 64 }
  validates :description, length: { maximum: 255 }
  validate do |student_additional_field|
    if student_additional_field.validation_pattern.present? &&
        student_additional_field.validation_type == 'custom'
      begin
        Regexp.new(student_additional_field.validation_pattern)
      rescue RegexpError => e
        errors.add(:validation_pattern, 'Validation pattern is invalid regex')
      end
    end
  end

  scope :by_admission, -> { where(admissions: 1) }
  scope :by_group, ->(id) { where(group_id: id) if id }
  scope :by_ids, ->(ids) { where(id: ids) if ids }
  scope :ordered, -> { order(:order) }

  scope :joins_application_fields, ->(id, flag=true) do
    query = joins(:admission_additional_fields)
      .where(admission_additional_fields: { application_id: id, display: true })
    return query if flag

    where.not(id: query)
  end

  scope :joins_application, ->(id) do
    joins(:admission_additional_fields).where(admission_additional_fields: { application_id: id })
  end

  def students_with_values
    count = student_additional_values.distinct.pluck(:student_id).count
    count + admission_additional_values.distinct.pluck(:applicant_id).count
  end

  def destroy_attached_values
    transaction do
      student_additional_values.destroy_all
      admission_additional_values.destroy_all
    end
  end

  private
    def remove_choices
      choices.destroy_all
    end

    def update_rpid
      update(RPID: id)
    end
end
