class Product < ActiveRecord::Base

  # todo do we really need :product_documents on a next line?
  attr_accessible :code, :main_image_uri, :main_image_uri_cache, :title, :body, :manufacturer_id, :catalogue_category_id, :related_product_ids, :published, :product_documents_attributes, :product_images_attributes, :related_products_attributes, :product_documents, :id_for_relation, :specifications
  attr_accessor :id_for_relation

  has_many :product_documents, :dependent => :destroy
  accepts_nested_attributes_for :product_documents, :reject_if => lambda { |i| i[:id].blank? && i[:uri].blank? && i[:uri_cache].blank? }, :allow_destroy => true

  has_many :product_images, :dependent => :destroy
  accepts_nested_attributes_for :product_images, :reject_if => lambda { |i| i[:id].blank? && i[:uri].blank? && i[:uri_cache].blank? }, :allow_destroy => true

  has_and_belongs_to_many :related_products, :class_name => 'Product', :join_table => :products_relations, :foreign_key => :product_id, :association_foreign_key => :related_product_id
  #accepts_nested_attributes_for :related_products, :reject_if => :check_and_add_related_product, :allow_destroy => true
  accepts_nested_attributes_for :related_products, :reject_if => :check_and_add_related_product

  has_and_belongs_to_many :orders

  belongs_to :manufacturer

  belongs_to :catalogue_category

  mount_uploader :main_image_uri, ProductMainImageUploader

  # validation

  validates_presence_of :title
  validates_length_of :title, :maximum => 256

  validates_presence_of :manufacturer_id
  validates_presence_of :catalogue_category_id

  # scopes
  default_scope order('products.title ASC')
  #scope :visible_to_user, where(:published => true)
  scope :visible_to_user, lambda { joins(:manufacturer).where(products: {published: true}, manufacturers: {published: true}) }

  # stuff

  define_index do
    indexes title, sortable: true
    indexes code
    #indexes body
    #indexes catalogue_category(:title), as: :catalogue_category
    has published
    has manufacturer_id
    has catalogue_category_id
    has updated_at
    #set_property field_weights: {
    #    code: 3,
    #    title: 3,
    #    body: 1
    #}
    set_property delta: true
  end

  #sphinx_scope(:sphinx_default_scope) {
  #  {order: 'title ASC', star: true}
  #}
  #
  #default_sphinx_scope :sphinx_default_scope

  def id_for_relation
    @id_for_relation || id
  end

  def has_any_info?
    not (body.blank? && specifications.blank? && product_documents.empty? && related_products.empty?)
  end

  def has_only_body?
    !body.blank? && (specifications.blank? && product_documents.empty? && related_products.empty?)
  end

  def new_from_copy
    copy = dup
    copy.code = nil

    copy
  end

  def specification_rows_only
    rows_only = specifications.dup
    rows_only.slice! "<table>"
    rows_only.slice! "</table>"
    rows_only
  end

  private

  def check_and_add_related_product(attributes)
    if !attributes['id_for_relation'].nil? && !attributes['id_for_relation'].blank?
      related_product = Product.find(attributes['id_for_relation'])
      # id_for_relation - NEW related product
      # id - OLD related product, if it is edited
      if related_product

        if !attributes['id'].nil? && attributes['id'] != attributes['id_for_relation'] # updated record
          old_related_product = Product.find(attributes['id'])
          self.related_products.delete(old_related_product)
        end

        if !self.related_products.include?(related_product)
          self.related_products << related_product
        end

        return true
      end
    end

    return false
  end

end
