class Institution < ActiveRecord::Base

  # Accessors
  attr_accessible :name, :institution_type_id, :acronym, :ranked, :at_complaints, :website_url, :facebook_url, :twitter_url,
    :at_information_requests, :accepts_online_information_requests, :information_request_correlative, :transparency_external_portal_url,
    :reproduction_amount, :certification_amount, :administrative_document_type

  # Non database attributes
  attr_accessible :information_officer_attributes, :institution_services_attributes, :logo, :header,
    :information_standard_category_id, :institution_information_standards_settings_attributes

  attr_accessible :administrative_record

  DocumentType = {
    0 => "Acto administrativo",
    1 => "Declaratoria de Inexistencia"
  }

  # Paperclip
  has_attached_file :administrative_record

  # Associations
  has_one :information_officer
  has_many :information_requests
  has_many :information_ranking_histories
  has_many :information_rankings, through: :information_ranking_histories, uniq: true
  has_many :complaints
  belongs_to :institution_type
  belongs_to :information_standard_category
  has_many :information_standards, through: :information_standard_category
  has_many :information_standard_frames, through: :information_standards, uniq: true
  has_many :institution_services, order: :name
  has_many :institution_service_categories, order: :name
  has_many :documents, order: 'created_at desc'
  has_many :document_categories
  has_many :institution_organizational_structures
  has_many :institution_officials, order: :name
  has_many :institution_consultants, order: :name
  has_many :institution_remunerations, order: :name
  has_many :institution_travels, order: 'start_date desc'
  has_many :institution_calendars, dependent: :destroy
  has_many :procurements, order: :name, dependent: :destroy
  has_many :resources_to_private_recipients, order: :name, dependent: :destroy
  has_many :executing_works, order: :name, dependent: :destroy
  has_many :committees, dependent: :destroy
  has_many :institution_recruitment_results, dependent: :destroy
  has_many :institution_inventory_categories, dependent: :destroy
  has_and_belongs_to_many :inventory_managers, class_name: 'User', association_foreign_key: :inventory_manager_id, join_table: 'institutions_inventory_managers'

  has_many :institution_information_standards_settings, dependent: :destroy
  accepts_nested_attributes_for :institution_information_standards_settings, allow_destroy: true

  has_many :institution_maintenance_information_standards, dependent: :destroy
  accepts_nested_attributes_for :institution_maintenance_information_standards, allow_destroy: true

  has_many :institution_links, dependent: :destroy
  accepts_nested_attributes_for :institution_links, allow_destroy: true

  has_many :shared_information_standards,
           through: :institution_information_standards_settings,
           class_name: InformationStandard,
           source: :information_standard

  has_many :budget_units, dependent: :destroy
  has_many :line_of_works, through: :budget_units
  has_many :ta_discussions
  has_and_belongs_to_many :notice_complaints

  # Paper trail, track changes
  has_paper_trail

  accepts_nested_attributes_for :information_officer
  accepts_nested_attributes_for :institution_services, reject_if: :all_blank, allow_destroy: true

  # Validations
  validates :name, :institution_type_id, :acronym, presence: true
  validates :information_standard_category_id, presence: true, if: :ranked?
  validates :information_request_correlative, numericality: { only_integer: true, greater_than: 0 }

  # FriendlyId
  extend FriendlyId
  friendly_id :name, :use => [:slugged, :history]

  # Scopes
  scope :with_institution_services, includes(:institution_services).
    where('IFNULL(institution_services.active, 0) = 1').
    where('institution_services.id IS NOT NULL')

  scope :without_dontknow, where("id != 118").reorder("name ASC")

  # Paperclip
  has_attached_file :logo,
    content_type: ['image/jpeg', 'image/jpg', 'image/png'],
    styles: { original: '104x78>' },
    default_style: :original

  has_attached_file :header,
    content_type: ['image/jpeg', 'image/jpg', 'image/png'],
    styles: { original: '660x200#' },
    default_style: :original

  def last_information_ranking_fulfillment_percent
    information_ranking = information_rankings.where(published: true).order('closed_at desc').first
    return nil if information_ranking.nil?
    score = 0
    information_ranking_histories.where(information_ranking_id: information_ranking.id).each do |history|
      info = InformationStandardInfo.where(information_standard_id: history.information_standard_id, information_standard_category_id: information_standard_category.id).first
      score += (history.score / 100 / 10 * (info.nil? ? 0 : info.percent))
    end
    score
  end

  def next_correlative
    self.update_column(:information_request_correlative, information_request_correlative.to_i + 1)
  end

  before_validation :mark_institution_information_standards_settings_for_destruction

  def mark_institution_information_standards_settings_for_destruction
    institution_information_standards_settings.each do |institution_information_standards_setting|
      if institution_information_standards_setting.related_institution_id.blank?
        institution_information_standards_setting.mark_for_destruction
      end
    end
  end

  # returns information standards associated
  # through standard category and
  # associated through another institution
  #
  def full_information_standards
    information_standards + shared_information_standards
  end

  def average_time_per_information_request
    request_days = information_requests.confirmed.map(&:process_days).compact
    return nil unless request_days.size > 0
    (request_days.inject(:+).to_f / request_days.size).round(1) rescue nil
  end

  def score_by_ranking information_ranking
    score = 0.0
    information_ranking_histories.where(information_ranking_id: information_ranking.id).each do |history|
      info = InformationStandardInfo.where(information_standard_id: history.information_standard_id, information_standard_category_id: information_ranking.information_standard_category_id).first
      score += (history.score / 100 / 10 * (info.nil? ? 0 : info.percent))
    end
    score
  end
end
