class PCustomer < ApplicationRecord
  
  acts_as_tree
  
  has_many :price_documents
  
  has_many :particulars, :as => :owner, :dependent => :destroy
  
  has_many :p_contact_ps, :class_name => "PContact", :through => :particulars, :source => :p_contacts
  
  has_many :p_contacts, :as => :contactable, :dependent => :destroy
  accepts_nested_attributes_for :p_contacts, allow_destroy: true
  
  has_many :p_customer_sheets
  
  has_many :p_sheet_lines, :through => :p_customer_sheets
  
  has_many :p_products, :through => :p_customer_sheets
  
  
  accepts_nested_attributes_for :particulars
  
  belongs_to :particular
  accepts_nested_attributes_for :particular
  
  has_many :p_payments
  
  belongs_to :p_customer_cat
  
  has_many :p_documents
  
  #validates :code, :presence => true, :uniqueness => true
  
  has_many :p_compta_elements
  
  belongs_to :accounting_zone
  
  belongs_to :market_discount
  
  has_many :timer_watchers
  
  has_many :open_range_elements, :as => :element
  
  has_many :open_ranges, :through => :open_range_elements
  
  belongs_to :p_commercial

  has_many :mail_hists
  
  has_many :m_odr_rep_ribs, :dependent => :destroy

  has_many :m_odr_files

  has_many :m_odr_primes


  has_many :p_customer_ribs, :dependent => :destroy
  accepts_nested_attributes_for :p_customer_ribs, :allow_destroy => true
  

  has_secure_password validations: false
  
  
  validates :password, :presence => true, :if => :password_needed?
  
  validates :password, confirmation: { case_sensitive: true }, :presence => true, :if => :password_needed?
  
  
  validates :email, :presence => true, :uniqueness => true

  validates :cgv, :presence => true, :if => :require_cgv
  #validates :rgpd, :presence => true, :if => :require_cgv
  
  validates :past_id, :uniqueness => true, :if => :imported
  
  attr_accessor :refresh_import
  
  def do_import
    if self.imp_iban? and self.imp_bic?
      puts "RIB PRESENT"
      if rib = self.m_odr_rep_ribs.first
        puts "RIB EXISTANT"
        rib.iban = self.imp_iban
        rib.bic = self.imp_bic
        rib.admin_ok = false
        rib.save
      else
        puts "RIB CREER"
        self.m_odr_rep_ribs.create(:bic => self.imp_bic, :iban => self.imp_iban, :admin_ok => nil)
      end
    end
    
    if self.imp_test == "oui"
      self.test_user = true
    end
    
    if self.particular
      part = self.particular
    else
      part = Particular.new
      part.owner = self
    end
    part.name = self.imp_name
    part.firstname = self.imp_firstname
    part.address_2 = self.imp_address
    part.cp = self.imp_cp2
    part.city = self.imp_city
    part.country = "FR" if !part.country?
    part.tel = self.imp_tel
    
    self.particular = part
    
    if self.imp_valid ==  "oui"
      self.enabled = true
    end
    
    if self.imp_npai ==  "oui"
      self.npai = true
    end
    
    if self.imp_stickers ==  "oui"
      self.sticker = true
    end
    
    if circuit = Circuit.where(:past_id => self.imp_circuit_1).first
      self.circuit_1_id = circuit.id
    end
    
    if circuit = Circuit.where(:past_id => self.imp_circuit_2).first
      self.circuit_2_id = circuit.id
    end
    
    if circuit = Circuit.where(:past_id => self.imp_circuit_3).first
      self.circuit_3_id = circuit.id
    end
    
    part.save
    
    self.particular = part
    self.refresh_import = nil
    self.save
    
    
    
  end
  
  after_create do
    puts "TEST1"
    puts self.imp_email?
    puts "TEST2"
    self.do_import() if self.imp_email?
  end
  
  after_update do
    self.do_import if self.refresh_import == "true"
  end
  
  acts_as_csv_import :fields =>[:imported, :email, :password, :past_id,:imp_cp,:imp_country,:imp_ref,:imp_email,:imp_firstname,:imp_name,:imp_fonction,:imp_organisme,:imp_address,:imp_cp2,:imp_city,:imp_tel,:imp_portable,:imp_lien,:imp_comment,:imp_iban,:imp_bic,:imp_circuit_1,:imp_circuit_2,:imp_circuit_3,:imp_partenaire,:imp_ecran,:imp_blocage,:imp_valid,:imp_user_valid,:imp_offre,:imp_info,:imp_cgu,:imp_test,:imp_stickers,:imp_npai,:npai,:imp_relance_adresse,:imp_demande_info,:imp_creation,:imp_modification, :refresh_import]
  
  attr_accessor :actual_password, :valid_last_password, :valid_public, :generate_mdp, :valid_pswd_confirmation, :require_cgv

  NBR_ROULAGES = ["Entre 1 et 2", "Entre 3 et 5", "Entre 6 et 8", "Entre 9 et 10", "> 10", "Pas pour l'instant"]

  def particular_ok?
    
    if self.particular and self.particular.address_2? and self.particular.cp? and self.particular.city? and self.particular.country?  
      true
    else
      false
    end
    
  end

  def valid_m_odr_rep_rib
    self.m_odr_rep_ribs.where(:admin_ok => true).order("id DESC").first
  end


  def verify_actual_password
    self.authenticate(self.actual_password)

  end

  def password_needed? 
   if (!self.id and (!self.generate_mdp or self.generate_mdp == "0")) or self.valid_pswd_confirmation
     true
    
   else
     false
   end
     
  end

  after_commit do
    self.generate_mdp_now if self.generate_mdp and self.generate_mdp != "0"
  end


  before_validation do
    
    
    
    if self.valid_last_password and !PCustomer.find(self.id).authenticate(self.actual_password)
      errors.add(:actual_password, 'ne correspond pas au mot de passe actuel')
    end
  end
  
  before_create do 
    generate_token(:auth_token)
  end
  def generate_token(column)
    begin
        self[column] = SecureRandom.urlsafe_base64
    end while PCustomer.exists?(column => self[column])
  end
      
    
  def generate_prime
    MOdrFileRoulage.joins(:m_odr_file).where("m_odr_file_roulages.nbr_primes_useds = 0").where(:m_odr_files => {:p_customer_id => self.id, :admin_ok => true}).order("date ASC").all.each do |mofr|
      mofr.generate_prime
    end  
  end
  
  def generate_mdp_now
    ps = SecureRandom.hex(4)
    self.password = ps
    self.password_confirmation = ps
    
    if !self.email?
      errors.add(:email, "Doit être présent") 
      
    end
    
    self.generate_mdp = false
    if self.save
      #GeneralMailer.send_qi_mail("fr", "generation_mdp", self.email, {"mdp" => ps}).deliver

      mail_hist = MailHist.generate_mail(:fr, MailType.find_by_slug("generation_mdp"), self.email, {:arguments => {:mdp => ps, :civilite => self.particular.civilite, :nom => self.particular.name, :prenom => self.particular.firstname  }, :p_customer => self, :element => self})

    else

    end
    
    
  end


  
  def self.qi_table_order
    {
      :created_at => {:name => "Date de création", :reorder => true, :as => :date},
      :show_name => "Nom",
      :mlm_token => {:name => "Code ambassadeur", :reorder => true},
      :enabled => "Actif ?",
      :parent => "Ambassadeur",
      :particular => "Ville",
      :actions => "Actions"
     
    }
    #, :sort_name => "code"
  end
  
  def self.valid_sort
    
    ["code", "created_at", "cache_encours_th", "cache_encours", "cache_payments_th", "cache_payments", "cache_payments_tot", "cache_ca"]
    
  end
  
  
  before_destroy do
    if self.p_customer_sheets.count > 0 or self.p_payments.count > 0
      false
    else
      true
    end
      
  end
  
  def can_destroy?
    if self.p_customer_sheets.count > 0 or self.p_payments.count > 0
      return false
    else
      return true
    end
  end
  
  after_initialize do
    self.p_payment_type_id = 41 if !self.p_payment_type_id?

  end
  
  
  def self.find_parrain(token)

    
    if token != ""
      self.find_by_mlm_token(token.upcase)
    else
      nil
    end
  end
  
  
  before_validation do
    
    
    
    generate_mlm_token
    
    
    if !self.id
      if self.parent_code?

        if mlm_parent = PCustomer.find_parrain(self.parent_code)
          self.parent_id = mlm_parent.id
          self.parent_at_create = true
        else
          errors.add(:parent_code, "Ce code ambassadeur n'est pas valide, merci de vérifier son exactitude. ")
        end
      end
    end
    
    
    
    if self.comptant
      
      if self.acompte
        errors.add(:acompte, "N'est pas compatible avec les paiements comptants") 
        
      end
      
      if self.acompte_percent?
        errors.add(:acompte_percent, "N'est pas compatible avec les paiements comptants") 
        
      end
      
      if self.payment_delais?
        errors.add(:payment_delais, "N'est pas compatible avec les paiements comptants") 
        
      end
      
      if self.payment_fin_de_mois
        errors.add(:payment_fin_de_mois, "N'est pas compatible avec les paiements comptants") 
        
      end
      
      
      
      
      
    end
    
    if self.acompte
      if !self.acompte_percent?
        errors.add(:acompte_percent, "Doit être remplis pour demander un acompte") 
      end
    end
    
    
    if !self.comptant
      if !self.payment_delais?
        errors.add(:payment_delais, "Délais de paiement nécessaire si pas de paiement comptant") 
      end
    end
    
  end
  
  
  def update_caches
    
    
    
    
  end
  
  def ca_ht
    0
  end
  
  def ca_ttc
    0
  end
  
  def nbr_orders
    self.p_customer_sheets.where(:state => "facturée")
    
  end
  
  def nbr_orders_refusees
    self.p_customer_sheets.where(:state => "refusée")
    
  end
  
  
  def encours_assure
    r = 0.0
    r = self.p_customer_cat.encourt_max if self.p_customer_cat
    r
  end
 
  def encours_assure_restant
    self.encours_assure.to_f - self.encours_ttc.to_f
  end
  
  def encours_ttc
    self.solde_avoir_and_bills - self.paiements_total
  end
  
  def th_r_encours_ttc
    self.solde_avoir_and_bills - self.th_r_paiements_total
  end
  
  
  def encours_at(date)
    self.solde_avoir_and_bills(date) - self.paiements_total(date)
  end
  
  
  def sheets_total_ht
    self.p_customer_sheets.where(:state => "facturée").sum(:cc_tot_amount_ht)
  end
  
  def solde_avoir_and_bills(date = Date.today)
    self.p_documents.where(:p_document_type_id => [4,7]).where("created_at < ?", date.to_time.end_of_day).sum(:cache_total_ttc)
    
  end
  
  def sheets_total_ttc(date = Date.today)
    self.p_customer_sheets.where(:state => "facturée").where("created_at < ?", date.to_time.end_of_day).sum(:a_ok_total_ttc)
  end
  
  def paiements_total(date = Date.today)
    self.p_payments.where(:paid => true).where("paid_at < ?", date.to_time.end_of_day).sum(:amount)
    
  end
  
  def th_paiements_total
    self.p_payments.where(:paid => false).sum(:amount)
    
  end
  
  def th_r_paiements_total
    self.p_payments.sum(:amount)
    
  end
  
  
  def self.for_search(search)
    PCustomer.joins(:particulars).where("code LIKE ? or particulars.organisation LIKE ? or particulars.name LIKE ? or particulars.firstname LIKE ? or particulars.address_2 LIKE ? or particulars.address_3 LIKE ? or particulars.cp LIKE ? or particulars.city LIKE ?","%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%","%#{search}%", "%#{search}%", "%#{search}%", "%#{search}%").uniq
  end
  
  def generate_mlm_token
    if !self.mlm_token?
      self.mlm_token = loop do
   
      mlm_token = SecureRandom.hex(3).upcase
        break mlm_token unless PCustomer.exists?(mlm_token: mlm_token)
      end
      
    end
  end
  

  def name
    self.show_name
  end

  def member_label
    self.show_name
  end


  def show_name
    if self.particular
      n = ""
      n += self.particular.organisation+" " if self.particular.organisation?
      
      n += self.particular.firstname+" " if self.particular.firstname?
      n += self.particular.name+" " if self.particular.name?
      return n
    end
  end
  
  
  def show_name_extend
    if self.particular
      n = ""
      n += self.code.to_s+" "
      n += self.particular.organisation+" " if self.particular.organisation?
      n += self.particular.name+" " if self.particular.name?
      n += self.particular.firstname+" " if self.particular.firstname?
      n += self.particular.cp+" " if self.particular.cp?
      n += self.particular.city+" " if self.particular.city?
      return n
    end
  end
  

  after_save do
    if !self.particular  and self.particulars.count > 0
      self.particular = self.particulars.first
      self.save
      
    end
      
      
  end
  
  def archive_import
    past_fact = self.p_documents.where("d_number regexp '^[0-9]+'").order("created_at DESC")
    if past_fact.first
      date = past_fact.first.created_at + 1.second
      amount = past_fact.sum(:cache_total_ttc)
      if !self.p_payments.where(:p_payment_type_id => 66).first

        p_payment = self.p_payments.new(:p_payment_type_id => 66, :imported => true, :paid => true, :paid_at => date, :amount => amount)
        
        p_payment.save
      end
    end
    
    PPayment.where(:imported => true).update_all(:paid => true)
    date = nil

    self.p_payments.order("paid_at DESC").each do |pp|
      enc = self.encours_at(pp.paid_at)
   
        
      if enc == 0.0
        date = pp.paid_at.end_of_day
        break
      end
    end
    
    
    self.p_customer_sheets.where(:state => "facturée", :imported => true).update_all(:i_archive => false)
    self.p_documents.where(:label => "Facture", :imported => true).update_all(:i_archive => false)
    self.p_payments.where(:imported => true).update_all(:i_archive => false)
    
    self.p_customer_sheets.where(:state => "facturée", :imported => true).where("created_at < ?", date).update_all(:i_archive => true)
    self.p_documents.where(:label => "Facture", :imported => true).where("created_at < ?", date).update_all(:i_archive => true)

    self.p_payments.where(:imported => true).where("paid_at < ?", date).update_all(:i_archive => true) if date
    
    return true
    
  end
  

end
