#this class handles user login and password. User has the attributes user name, email and password which he / she can choose
class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include ActiveModel::SecurePassword

  field :user_name, type: String
  field :password_digest, type: String
  field :confirmation_token, type: String
  field :reset_token, type: String
  field :approved, type: Boolean, :default => false
  has_many :assets
  has_many :user_actions, :dependent => :destroy

  index({ confirmation_token: 1}, { unique: true })
  scope :unapproved, ->{ where(approved: false) }

  has_secure_password

  belongs_to :workgroup
  has_many :authorizations
  belongs_to :member_profile
  has_one :facebook, :autosave => true, :dependent => :destroy
  has_one :desktop, :dependent => :destroy


  validates :user_name, uniqueness: true
  validates :password, :on => :create, length: {:in => 8..20}

  #Add getter and setter for email virtual field
  attr_accessor :email, :first_name, :last_name

  def generate_confirmation_token
      self.confirmation_token = SecureRandom.hex(5)
      self.save
  end

  def self.confirm_email(confirmation_token = nil)
    if confirmation_token
      user = self.find_by(confirmation_token: confirmation_token) rescue nil
      token_status = user.present?
      case token_status
      when true
        user.confirmation_token = nil
        user.save
        return {:success => "true", :id => user.id.to_s}
      when false
        return {:success => "false"}
      end
    else
        return {:success => "false"}
    end
  end

  def generate_reset_token
      self.reset_token = SecureRandom.hex(5)
      self.save
  end

  def send_password_reset_email
    self.generate_reset_token
    ResetPasswordMailer.reset_user_password(self).deliver
  end

  def self.check_password_token(reset_token = nil)
    user = self.find_by(reset_token: reset_token) rescue nil
    token_status = user.present?
    if token_status
      true
    else
      false
    end
  end

  def update_password(password, password_confirmation)
    self.update_attributes(password: password, password_confirmation: password_confirmation, reset_token: nil)
    self.save
  end

  def is_confirmed?
    if self.confirmation_token.present?
      false
    else
      true
    end
  end

  def is_admin?
    if (self.workgroup.present? && self.workgroup.key.eql?("admin"))
      true
    else
      false
    end
  end

  def is_approved?
    self.approved
  end

  def is_manager?(module_app)
    if ((module_app.user_module_managers.include?(self.id) rescue nil) && (!self.is_admin?))
      true
    else
      false
    end
  end
  
  def is_sub_manager?(module_app)
    module_app_categories = module_app.categories.map {|c| c.id} rescue nil
    authorized_categories = self.authorizations.map {|a| a.category.id if (a.category.present? && a.workgroup.key.eql?("sub_managers"))}
    intersection = (module_app_categories & authorized_categories)
    if ((intersection.count > 0 if intersection.present?) && !self.is_admin? && !self.is_manager?(module_app))
      true
    else
      false
    end
  end

  def is_manager_with_role?(module_app)
    user_roles = self.member_profile.role_ids.map {|r| r}
    authorized_roles = module_app.role_managers rescue []
    intersection = (user_roles & authorized_roles)

    if (intersection.count > 0 if intersection.present?)
      true
    else
      false
    end
  end

  def is_sub_manager_with_role?(module_app)
     user_roles = self.member_profile.role_ids.map {|r| r}
     authorized_categories = []
     wg = Workgroup.find_by(:key => "sub_managers")
     user_roles.each do |r|
        auths =  Authorization.find_by(:rold_id  => r, :workgroup_id => wg.id) rescue []
        auths = auths.to_a if !auths.kind_of?(Array)
        auths.each do |a|
          authorized_categories << a.category
        end
     end
    module_app_categories = module_app.categories.map {|c| c.id} rescue nil
    intersection = (module_app_categories & authorized_categories)
     if (intersection.count > 0 if intersection.present?)
      true
    else
      false
    end
  end

  def is_normal_user?
    if self.is_admin?
      return false
    elsif self.authorizations.empty?
      return true
    else
      return false
    end
  end

  def approved_categories_for_module(module_app)
    module_app_categories = module_app.categories rescue []
    authorized_categories = self.authorizations.map {|a| a.category if (a.category.present? && a.workgroup.key.eql?("sub_managers"))}
    intersection = (module_app_categories & authorized_categories)
    intersection
  end

  def approved_categories
    categories = []
    if self.is_admin?
      Category.all.each do |c|
        categories << c
      end
    else
      authorizations = self.authorizations.collect{|a| a} 
      user_roles = self.member_profile.roles rescue []
      user_roles.each do |r|
        authorizations.concat((r.authorizations rescue []))
      end

      authorizations.each do |auth|
        case auth.workgroup.key
        when "managers"
          cats = auth.module_app.categories rescue []
          if !cats.blank?
            cats.each do|c|
              categories << c
            end
          end
        when "sub_managers"
          c = Category.find(auth.category_id) rescue nil
          categories << c if !c.nil?
        end
      end
    end
    categories
  end

  def user_workgroup(module_app)
    if self.is_admin?
      "Admin"
    elsif (self.is_manager?(module_app) || is_manager_with_role?(module_app))
      "Manager"
    elsif self.is_sub_manager?(module_app)
      "Sub Manager"
    end
  end

  def self.not_admins
    workgroup = Workgroup.find_by(key: "admin")
    self.where(:workgroup_id.ne => workgroup.id) 
  end

end