class AnnonceAccount < ActiveRecord::Base
  
  has_many :annonce_account_favs
  has_many :annonce_favs, :through => :annonce_account_favs, :class_name => "Annonce", :source => :annonce
  
  has_many :annonces
  has_many :annonce_photos, :through => :annonces
  
  has_many :annonce_account_newsgroups
  has_many :newsgroups, :through => :annonce_account_newsgroups
  
  has_many :credits
  has_many :expenses
  has_many :credit_expenses
  has_many :mlm_points
  has_many :orders
  has_many :commissions
  has_many :virements
  has_many :hipay_virements
  has_many :binary_points
  has_many :inbox_messages, :class_name => "AnnonceMessage", :foreign_key => :destinataire_id
  has_many :annonce_account_ribs
  
  has_many :ip_histories
  
  has_secure_password

  validates_presence_of :name, :unless => :pro?
  validates_presence_of :firstname, :unless => :pro?
  
  validates_presence_of :organisation, :if => :pro?
  
  validates_presence_of :password, :on => :create
  validates :email, :presence => true, :uniqueness => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

  validates :address, :presence => true, :if => :force_address?
  validates :cp, :presence => true, :if => :force_address?
  validates :city, :presence => true, :if => :force_address?
  validates :country, :presence => true, :if => :force_address?
  
  scope :enableds, lambda {
    where("annonce_accounts.deleted_at is null" ).where("annonce_accounts.blocked = 0 or annonce_accounts.blocked is NULL")
  }
  
  
  
  def set_facebook_friends
    begin
      @graph = Koala::Facebook::API.new(self.facebook_token)
      friends = @graph.get_connections("me", "friends")
      if friends and friends.raw_response["summary"] and friends.raw_response["summary"]["total_count"].to_i > 0
    
        self.facebook_friends_number = friends.raw_response["summary"]["total_count"].to_i
        self.save
      
      end
    rescue
      puts "synchro friends impossible"
    end
    
  end
  
  
  
  
  def not_blocked
    if !self.blocked and !self.deleted_at
      true
    else
      false
    end
  end
  
  attr_accessor :force_address
  
  def force_address?
    self.force_address
  end
  
  
  mount_uploader :avatar, AvatarUploader
  
  COUNTRY = [
    
    "Suisse", 
    "France",   
    "Allemagne",
    "Autriche", 
    "Belgique", 
    "Espagne", 
    "Estonie", 
    "Finlande",
    "Grèce",
    "Irlande",
    "Italie",
    "Luxembourg",
    "Malte",
    "Pays-Bas",
    "Portugal",
    "Slovaquie",
    "Slovénie",
    "Croatie",
    
    
    "Bulgarie",
    "Danemark", 
    "Hongrie", 
    "Lettonie", 
    "Lituanie", 
    "Pologne", 
    "République Tchèque", 
    "Roumanie", 
    "Royaume Uni", 
    "Suède",
    "Islande", 
    "Norvège",
    "Liechtenstein",
    "Monaco",
    
    "Guadeloupe",
    "Guyane",
    "Martinique",
    "La Réunion",
    "Mayotte",
    "Polynésie française",
    "Saint-Barthélemy",
    #"Saint-Martin",
    #"Saint-Pierre-et-Miquelon",
    "Wallis-et-Futuna",
    "Nouvelle-Calédonie"
 
    
    
    
  ]
  
  COUNTRY_ORDER = [
    
    "Suisse", 
    "France",   
    "Allemagne",
    "Autriche", 
    "Belgique",
    "Canada",
    "Espagne", 
    "Estonie", 
    "Finlande",
    "Grèce",
    "Irlande",
    "Italie",
    "Luxembourg",
    "Malte",
    "Pays-Bas",
    "Portugal",
    "Slovaquie",
    "Slovénie",
    "Croatie",
    
    
    "Bulgarie",
    "Danemark", 
    "Hongrie", 
    "Lettonie", 
    "Lituanie", 
    "Pologne", 
    "République Tchèque", 
    "Roumanie", 
    "Royaume Uni", 
    "Suède",
    "Islande", 
    "Norvège",
    "Liechtenstein",
    "Monaco",
    
    "Guadeloupe",
    "Guyane",
    "Martinique",
    "La Réunion",
    "Mayotte",
    "Polynésie française",
    "Saint-Barthélemy",
    #"Saint-Martin",
    #"Saint-Pierre-et-Miquelon",
    "Wallis-et-Futuna",
    "Nouvelle-Calédonie"
 
    
    
    
  ]
  
  
  acts_as_tree
  before_create do
    self.generate_mlm_token
    self.generate_token
   
  end
  
  before_validation do
    
    if !self.id
      if self.parent_code?
        
        if mlm_parent = AnnonceAccount.find_parrain(self.parent_code) 
          self.parent_id = mlm_parent.id
          self.parent_at_create = true
        else
          errors.add(:parent_code, "Ce code de recommandation n'est pas valide, merci de vérifier son exactitude. ") 
        end
      end
    end
    
  end
  
  after_create do 

    
    newsgroups = Newsgroup.where(:default_checked => true).all
    
    
    self.newsgroups << newsgroups
    
    if self.parent_at_create
      self.credits.create(:cred => true, :value => 10, :expire_after => Time.now+(6.months), :note => "Crédits offerts grâce au code de recommandation")
    
      self.parent.credits.create(:cred => true, :value => 5, :expire_after => Time.now+(6.months), :note => "Crédits offerts grâce à votre nouvel affilié")
    
    end
    
  end
  
  
  def mlm_detail_ids
    
    i = 0
  
    parents_id = [self.id]
  
    mlm_children_ids =  []
  
    mlm_children_id_by_levels =  []
  
    while i != 14 do
      i += 1
      
      
      parents_id = AnnonceAccount.where(:parent_id => parents_id).select(:id).map{ |v| v.id}
      
      mlm_children_id_by_levels[i] = parents_id
      mlm_children_ids.concat parents_id
      
      
      
    end
    
    {
      :mlm_children_id_by_levels => mlm_children_id_by_levels,
      :mlm_children_ids => mlm_children_ids
    }
    
  
  end
  
  def mlm_children_id_by_levels
     self.mlm_detail_ids[:mlm_children_id_by_levels] 
  end
  
  def mlm_children_ids
     self.mlm_detail_ids[:mlm_children_ids] 
  end
  
  def solde_commissions(devise_id=1)
    self.commissions.where(:devise_id => devise_id).sum(:amount)
  end
  
  
  def max_virement(devise_id=1)
    self.solde_commissions(1).floor - 5.0
    
  end
  
  def max_hipay_virement(devise_id=1)
    r = self.solde_commissions(devise_id).floor - 5.0
    if r < 0
      r =0
    end
    r
    
  end
  
  def send_password_reset

    
    begin
      self[:reset_password_token] = SecureRandom.urlsafe_base64
    end while AnnonceAccount.exists?(:reset_password_token => self[:reset_password_token])
    
    self.reset_password_sent_at = Time.now
    
    
    
    
    self.save(:validate => false)
    AnnonceAccountMailer.password_reset(self).deliver
  end
  
  
  def self.find_parrain(token)
    
    token = "B458AV" if token.to_s.upcase == "B458A0"
    token = "Y25D2G" if token.to_s.upcase == "O25D20"
    token = "Y25D2G" if token.to_s.upcase == "025D20"
    token = "Y25D2G" if token.to_s.upcase == "025D2O"
    token = "Y25D2G" if token.to_s.upcase == "O25D2O"
    
    
    if token.to_s != ""
      AnnonceAccount.find_by_mlm_token(token.downcase) 
    else
      nil
    end
  end
  
  def inscription_binaire
    
    if self.parent and !self.binary_parent_id
      
      parrain = self.parent 
      
      puts parrain.id
      
      if parrain.binary_preferences == 1
        
        self.binary_side = 1
      elsif parrain.binary_preferences == 2
        self.binary_side = 2
      else
        self.binary_side = parrain.less_leg

      end
    

      puts self.binary_side
      
      
      
      binary_filieul = find_binary_empty(parrain.id,self.binary_side )
      

      
      self.binary_parent_id = binary_filieul.id
      self.save(:validate => false)
      
      
      
    end
    
  end
  
  def pseudo
    if self.not_blocked
      if self.pro
        self.organisation
      else
        self.firstname+" "+self.name[0..0].to_s+"."
      end
    else
      "Utilisateur"
    end
  end
  
  def pseudo_admin
    if self.pro
      self.organisation
    else
      self.firstname+" "+self.name
    end
  end
  
  def avatar_url
    if self.avatar? 
      "https://sideplace.com/"+self.avatar.square.url 
    else
      if self.pro
        "/corporate-avatar.png"
      else
        "/avatar.png"
      end
    end
  end
  
  
  def self.get_tree(annonce_account)
      
        [annonce_account, get_tree(AnnonceAccount.where(:binary_side => 1, :binary_parent_id => annonce_account.id).first), get_tree(AnnonceAccount.where(:binary_side => 2, :binary_parent_id => annonce_account.id).first)] if annonce_account
        
  end
  
  
  
  def binary_parent
    AnnonceAccount.find(self.binary_parent_id) if self.binary_parent_id
    
  end
  
  
  def find_binary_empty(id, side)
    annonce_account = AnnonceAccount.find(id)
    if !annonce_account.find_binary(side)
      return annonce_account
    else
      self.find_binary_empty(annonce_account.find_binary(side).id, side)
      
    end
    
    
    
  end
  
  def find_binary(side)
    AnnonceAccount.where(:binary_side => side, :binary_parent_id => self.id).first
  end
  
  
  def generate_token
    begin
      self[:token] = SecureRandom.urlsafe_base64
    end while AnnonceAccount.exists?(:token => self[token])
  end
  
  def generate_mlm_token
     self.mlm_token = loop do
   
    mlm_token = SecureRandom.hex(3)
      break mlm_token unless AnnonceAccount.exists?(mlm_token: mlm_token)
    end
  end
  
  
  
  def credit_paid(cost, piece_id=nil, piece_type= nil, note="Achat option annonce" )
    if self.solde_credits(Date.today) >= cost
      
      expense = Expense.create(:annonce_account_id => self.id,:piece_id => piece_id, :piece_type => piece_type, :note => note, :value => cost)
      solde_cost = cost
      credits_to_use = self.credits.between(Date.today, Date.today).order("expire_after ASC")
      
      
      
      credits_to_use.each do |credit|
        if solde_cost > 0
          
          if solde_cost <= credit.solde
            
            CreditExpense.create(:value => solde_cost, :credit_id => credit.id, :annonce_account_id => self.id, :expense_id => expense.id)
            solde_cost = 0
            
          else
            
            partial_solde = credit.solde
            CreditExpense.create(:value => partial_solde, :credit_id => credit.id, :annonce_account_id => self.id, :expense_id => expense.id)
            
            solde_cost = solde_cost - partial_solde
            
            
            
          end
          
          
        end
        
      end
      
    else
      false
    end
    
  end
  
  def free_credits(date)
    credits_valides(date) - credits_boughts(date)
  end
  
  def credits_valides(date)
    self.credits.between(date, date).plus.sum(:value) 
  end
  
  def credits_boughts(date)
    self.credits.between(date, date).plus.boughts.sum(:value) 
  end
  
  
  def solde_credits(date)
    s = 0
    
    self.credits.between(date, date).each do |credit|
      s += credit.solde

    end
    
    return s
  
  end
  
  def update_left_binary_points
    self.left_binary_points = self.binary_points.left.sum(:value) 
    self.save
  end
  
  def update_right_binary_points
    self.right_binary_points = self.binary_points.right.sum(:value) 
    self.save
  end
  
  def binary_points_side(side)
    if side == 1
      self.left_binary_points 
    else
      self.right_binary_points 
    end
  end
  
  def less_leg
    if self.left_binary_points.to_i > self.right_binary_points.to_i
    
      return 2
    else
      return 1
      
    end
  end
  
  def strong_leg
    if self.left_binary_points.to_i < self.right_binary_points.to_i
    
      return 2
    else
      return 1
      
    end
  end
  def self.mlm_small_percents
    [0,10,6,4,4,4,4]
  end
  
  def self.mlm_big_percents
    [0,12,8,6,4,4,4,3,3,3,3]
  end
  
  
  def mlm_nbr_niveaux
    if self.callif_now
      if binary_active_count > 5
        self.callif_now[6]
      else
        self.callif_now[5]
      end
    else
      0
    end
  end
    
  CALLIFS = [["start", 40, 10,0,mlm_small_percents, 2,4], ["bronze", 120, 20,1, mlm_small_percents,3,5], ["silver", 260,30,3, mlm_small_percents,3,6], ["gold", 550, 40,8, mlm_big_percents,4,8], ["platinium", 1200,50,20, mlm_big_percents,5,10],["access", 15, 5,0,mlm_small_percents,2,3]]
  
  def callif_now
    self.callif(Date.today)
  end
  
  def callif(date)
    
    self.callif_credits(self.credits_boughts(date))
      
  end
  
  def callif_credits(credits_boughts)
    if credits_boughts >= 1200
      CALLIFS[4]
    elsif credits_boughts >= 550
      CALLIFS[3]
    elsif credits_boughts >= 260
      CALLIFS[2]
    elsif credits_boughts >= 120
      CALLIFS[1]
    elsif credits_boughts >= 40
      CALLIFS[0]
    elsif credits_boughts >= 15
      CALLIFS[5]
    end
  end
  
  def binary_percentage
    self.callif_now[2]
  end
  
  def commission_binary_now(order_ref=nil)
    if self.binary_active? and 1== 2
      less_value = self.binary_points_side(self.less_leg).to_i
    
      if less_value > 0
      
      
        commission_value = (less_value.to_f() * (self.binary_percentage.to_f()/100).to_f())

      
      
        com_object = self.commissions.create(:order => order_ref, :commission_type_id => 2, :amount => commission_value)
      
        self.binary_points.create(:value => less_value*(-1), :side => less_leg, :point_type => 2, :commission_id => com_object.id)
        self.binary_points.create(:value => less_value*(-1), :side => strong_leg, :point_type => 3, :commission_id => com_object.id)
      
      
      end
      
    end
    
  end
  def binary_active_count
    self.children.where("binary_parent_id is not null").count 
  end
  def binary_active?
    self.children.where("binary_parent_id is not null").count >= 2
    
    
  end
  
  def add_binary_child_ids(child_id)
    

      AnnonceAccount.where(:binary_parent_id => child_id).each do |ac|
        @ids << ac.id
        add_binary_child_ids(ac.id)
      end
      
      
    
  end
  
  def binary_child_ids
    
    @ids = []
    child_id = self.id
    
    add_binary_child_ids(child_id)
  
    return @ids
    
  end
  
end
