class User < ActiveRecord::Base
  enum role: [:user, :vip, :admin]
  after_initialize :set_default_role, if: :new_record?
  validates :email, presence: true, uniqueness: true
  validates :soft_token, presence: true, uniqueness: true
  has_many :canisters
  has_many :doodads
  has_many :projects
  has_many :profiles
  has_many :active_relationships, class_name:  "Relationship",
                                 foreign_key:  "follower_id",
                                   dependent:  :destroy
  # has_many :following, through: :active_relationships, source: :followed
  has_many :following_profiles, through: :active_relationships, source: :followable, source_type: "Profile"
  has_many :following_projects, through: :active_relationships, source: :followable, source_type: "Project"
  has_many :microposts, as: :micropostable
  has_many :bots
  has_many :messages

  def icid
    stp = SoftTokenPrincipal.where(soft_token: self.soft_token).first_or_initialize
    if stp.principal.nil?
      #TODO use principal
      if !soft_token.nil? 
        if `dfx identity use #{soft_token}; echo $?`.to_i == 255
        `dfx identity new #{soft_token} --disable-encryption`
          `dfx identity use #{soft_token}`
          @principal = `dfx identity get-principal`
          @icid = `dfx ledger account-id`
          `dfx identity use anonymous`
          stp.principal = @principal
          stp.save
        end
      end
    elsif
      `dfx identity use #{soft_token}`
      @icid = `dfx ledger account-id`
      `dfx identity use anonymous`
    end
    return @icid.strip
  end

  def principal
    stp = SoftTokenPrincipal.where(soft_token: self.soft_token).first_or_initialize
    if stp.principal.nil?
      #TODO use principal
      if !soft_token.nil? 
        if `dfx identity use #{soft_token}; echo $?`.to_i == 255
        `dfx identity new #{soft_token} --disable-encryption`
          `dfx identity use #{soft_token}`
          @principal = `dfx identity get-principal`
          `dfx identity use anonymous`
          stp.principal = @principal
          stp.save
        end
      end
    end
    return stp.principal.strip
  end

  def icp_balance
    `dfx identity use #{soft_token}`
    balance = `dfx ledger --network ic balance`
    `dfx identity use anonymous`
    return balance.strip
  end



  def set_default_role
    self.role ||= :user
  end

  def soft_user?
    self.email.empty?
  end

  def signed_in?
    !soft_user?
  end

  def to_s
    display_name
  end

  def display_name
    principal[0..4]
  end

  def sit_in(seat)
    seat.sit self
  end

  def stand_from(table)
    return if table == nil
    @seats = []
    if self.id
      @seats << table.seats.where(user_id: self.id)
    end
    if self.soft_token
      @seats << table.seats.where(user_soft_token: self.soft_token)
    end
    @seats.flatten.each do |seat|
      seat.stand(self)
    end
  end

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :invitable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  # Follows a followable leader
  def follow(leader)
    active_relationships.create(followable_id: leader.id, followable_type: leader.class.to_s)
  end

  # Unfollows a followable leader
  def unfollow(leader)
    active_relationships.find_by(followable_id: leader.id, followable_type: leader.class.to_s).destroy
  end

  def following
    active_relationships.map{|ar| ar.followable }
  end

  # Returns true if the current user is following the leader.
  def following?(leader)
    following.include?(leader)
  end

  def feed
    micropost_ids = []
    # Following posts
    if self.following.present?
      micropost_ids << self.following.map{|f| begin; f.microposts.pluck(:id); rescue; end;}.flatten
      end
    # Self posts
    micropost_ids << self.microposts.pluck(:id)
    # Flatten for SQL query
    micropost_ids.flatten!
    # Micropost.where("id IN (?)", micropost_ids)
    Micropost.where(id: micropost_ids)
  end

end
