class User
  include SimplyStored::Couch
  include ActiveModel::SerializerSupport

  property :name
  property :active_list_id
  property :admin, type: :boolean, default: false

  #FACEBOOK
  property :provider
  property :uid
  property :oauth_token
  property :oauth_expires_at
  property :auth_data

  devise_plugins = [:database_authenticatable, :recoverable, :rememberable, :trackable, :omniauthable, {omniauth_providers: [:facebook, :instagram]}] #, :token_authenticatable , :registerable
  devise_plugins -= [:trackable] if Rails.env.test? # creates conflicts
  devise *devise_plugins

  property :authentication_token

  has_and_belongs_to_many :lists, storing_keys: false
  has_many :orders
  has_many :list_payments

  validates_uniqueness_of :email
  before_save :ensure_authentication_token

  has_many :error_logs
  has_many :user_feedbacks

  view :by_authentication_token, key: :authentication_token
  view :by_email, key: :email
  view :by_facebook, key: [:provider, :uid] #DEPRICATE on successful change to by_provider
  view :by_provider, key: [:provider, :uid]

  def self.find_for_oauth(auth_data, user)
    user = database.view(self.by_provider(key: [auth_data.provider, auth_data.uid], limit: 1)).first

    user || create(
      provider: auth_data.provider,
      uid: auth_data.uid,
      name: auth_data.info.nickname,
      email: auth_data.info.email,
      password: Devise.friendly_token[0,20],
      oauth_token:  auth_data.credentials.token,
      oauth_expires_at: auth_data.credentials.expires ? Time.at(auth_data.credentials.expires_at) : nil,
      auth_data: auth_data
    )
  end

  def facebook_id
    uid
  end

  def provider_info
    case provider.to_sym
    when :facebook then {}
    when :instagram
      uri = URI.parse("https://api.instagram.com/v1/users/#{uid}?access_token=#{auth_data['credentials']['token']}")
      JSON.parse(Net::HTTP.get(uri)) rescue {ok: false, error: 'cannot_parse_response'}
    else
      {ok: false, error: 'provider_unknown'}
    end
  end

  def avatar
    return '' unless provider.present?
    case provider.to_sym
    when :facebook then "http://graph.facebook.com/#{uid}/picture?type=square"
    when :instagram then auth_data['info'].try(:[], 'image')
    end
  end

  def self.from_omniauth(auth)
    #binding.pry
  end

  def list_is_closed!
    self.active_list_id = nil
    save
  end

  # This is the user name as it is shown to the supplier
  def supplier_name
    auth_data['info']['name'] rescue I18n.t('supplier.user.unknown_name')
  end

  # This is the user name as it is shown to other users
  def friends_name
    auth_data['info']['nickname'] rescue name.to_s
  end

  def has_active_list?
    active_list_id.present?
  end

  # only used for testing so far
  def active_list
    has_active_list? ? List.find(active_list_id) : nil
  end

  #####################################
  # Taken from devise 2.2
  #####################################

  # Generate new authentication token (a.k.a. "single access token").
  def reset_authentication_token
    self.authentication_token = self.class.authentication_token
  end

  # Generate new authentication token and save the record.
  def reset_authentication_token!
    reset_authentication_token
    save(:validate => false)
  end

  # Generate authentication token unless already exists.
  def ensure_authentication_token
    reset_authentication_token if authentication_token.blank?
  end

  # Generate authentication token unless already exists and save the record.
  def ensure_authentication_token!
    reset_authentication_token! if authentication_token.blank?
  end

  def self.authentication_token
    SecureRandom.hex(24)
  end
end
