class MobileAppApi::V1::UserController < MobileAppApi::V1::BaseController

  before_filter :login_required!

  # Get User profile information by Its Id.
  def get_profile
    unless params[:user_id]
      user = @user
      conversation_id = nil
      is_friend = false
    else
      user = User.find(params[:user_id])
      conversation_id = ChatConversation.find_conversation([@user.id, params[:user_id]]).try(:id)
      is_friend = @user.common_friends.exists?(id: user)
    end
    render json: {status: 200, user_info: user.full_info.merge(user.activities_as_api).merge(user.info), conversation_id: conversation_id, reviews: user.try(:recieved_reviews), is_friend: is_friend}
  end

  # Method used to get all sessions(excluding rejected once) for current user to display on its dashboard.
  def get_dashboard
    data = @user.all_non_rejected_sessions_with_related_users
    data.merge!(@user.activities_as_api)
    render json: data.merge(status: 200)
  end

  # Method to get reviews information if user is fixxpert.
  def get_reviews
    if @user.fixxpert?
      render json: { status: 200 , reviews: @user.recieved_reviews.includes(:user).map(&:with_user_info), service_provider: @user.info}
    else
      render json: { status: 400 , error: "No service provider found with provided id / auth_token"}
    end
  end

  # Method to get the rate of current user if user is fixxpert.
  def get_rate
    if @user.fixxpert?
      render json: { status: 200 , rate: @user.rate_in_cents_with_charge, service_provider: @user.info}
    else
      render json: { status: 400 , error: "No service provider found with provided id / auth_token "}
    end
  end

  # Method to get the upcoming expert session of current user if user is fixxpert.
  def get_upcoming_session
   if @user.fixxpert?
      render json: { status: 200 }.merge(@user.confirmed_sessions_with_related_users.merge(user: @user.info))
    else
      data = @user.confirmed_sessions_with_related_users
      data[:upcoming] = data[:upcoming][:as_customer]
      render json: {status: 200}.merge(data.merge(user: @user.info))
    end
  end

  # Method to get the expert session history of current user if user is fixxpert.
  def get_session_history
    if @user.fixxpert?
      render json: { status: 200 }.merge(@user.confirmed_sessions_with_related_users(:previous).merge(user: @user.info))
    else
      data = @user.confirmed_sessions_with_related_users(:previous)
      data[:previous] = data[:previous][:as_customer]
      render json: {status: 200}.merge(data.merge(user: @user.info))
    end
  end

  # Method to get the count of profile visits of current user if user is fixxpert.
  def get_profile_visits
    if @user.fixxpert?
      render json: { status: 200 , visit_count: @user.profile_visits.sum(:count), user: @user.info}
    else
      render json: { status: 400 , error: "No service provider found with provided id / auth_token "}
    end
  end

  # Method to get rewards of the current user.
  def get_rewards
    begin
      query = ""
      query = (!params[:user_id].nil? && params[:user_id] != "") ? "id=#{params[:user_id]}" : "auth_token='#{params[:auth_token].strip}'"
      user = User.where(query)
      if !user.nil? && !user[0].nil?
        points = user[0].points
        user_info = {
          id: user[0].id,
          name: user[0].name,
          image: user[0].image,
          email: user[0].email
        }
        render json: { status: 200,
            :reward_points => points.nil? ? 0 : points,
            :user => JSON.parse(user_info.to_json)
          }
      else
        render json: { status: 400 , error: "No service provider found with provided id / auth_token"}
      end
    rescue => e
      render json: { status: 500 , error: "Something went wrong. Please try again with valid id.", error_details: e.message}
    end
  end

  # Method to get the level of the fixxpert.
  def get_level
    begin
      query = ""
      query = (!params[:user_id].nil? && params[:user_id] != "") ? "id=#{params[:user_id]}" : "auth_token='#{params[:auth_token].strip}'"
      fixxpert = Fixxpert.where(query)
      if !fixxpert.nil? && !fixxpert[0].nil?
        level = fixxpert[0].level
        user_info = {
          id: fixxpert[0].id,
          name: fixxpert[0].name,
          image: fixxpert[0].image,
          email: fixxpert[0].email
        }
        render json: { status: 200, level: level, user: JSON.parse(user_info.to_json) }
      else
        render json: { status: 400 , error: "No service provider found with provided id / auth_token "}
      end
    rescue => e
      render json: { status: 500 , error: "Something went wrong. Please try again later.", error_details: e.message}
    end
  end

  # Method to get converstaion between two users.
  def get_conversation_trail
    begin
      user1 = User.where(auth_token: params[:auth_token].strip)
      if user1.nil? || user1[0].nil?
        render json: { status: 400 , error: "No user found with provided auth_token."}
        return
      end
      user2 = User.where(id: params[:other_user])
      if user2.nil? || user2[0].nil?
        render json: { status: 400 , error: "No user found with id provided as a other_user"}
        return
      end
      page = params[:page]
      if !page.nil? && page != ""
        page_offset = (page.to_i - 1) * 50
      else
        page = 0
        page_offset = 0
      end
      msg_trail = Message.where("sender in (#{user1[0].id},#{user2[0].id}) and receiver in (#{user1[0].id},#{user2[0].id})").order('id desc').limit("#{page_offset},50")
      user = {
        id: user1[0].id,
        name: user1[0].name,
        image: user1[0].image.url,
        email: user1[0].email
      }
      o_user = {
        id: user2[0].id,
        name: user2[0].name,
        image: user2[0].image.url,
        email: user2[0].email
      }
      render json: {
          status: 200,
          page: page,
          conversation_trail: JSON.parse(msg_trail.to_json) ,
          user: JSON.parse(user.to_json),
          other_user: JSON.parse(o_user.to_json)
        }
    rescue => e
      render json: { status: 500 , error: "Something went wrong. Please try again later.", error_details: e.message}
    end
  end

  # APi to get unregistered referrals.
  def get_unregistered_referrals
    begin
      user = User.where(auth_token: params[:auth_token])
      if !user.nil? && !user[0].nil?
        unregistered_referrals = Invite.where({:registered => false, :inviter_id => user[0].id})
        user_info = {
          id: user[0].id,
          name: user[0].name,
          image: ActionController::Base.helpers.image_url(user[0].image.url),
          email: user[0].email
        }
        render json: {
          status: 200,
          referral_count: unregistered_referrals.nil? ? 0 : unregistered_referrals.length,
          unregistered_referrals: JSON.parse(unregistered_referrals.to_json),
          user: JSON.parse(user_info.to_json)
        }
      else
        render json: {status: 400, error: "User not found for auth_token #{params[:auth_token]}"}
      end
    rescue => e
      render json: { status: 500 , error: "Something went wrong. Please try again later.", error_details: e.message}
    end
  end

  # APi to get registered referrals.
  def get_registered_referrals
    begin
      user = User.where(auth_token: params[:auth_token])
      if !user.nil? && !user[0].nil?
        registered_referrals = Invite.where({registered: true, inviter_id: user[0].id})
        user_info = {
          id: user[0].id,
          name: user[0].name,
          image: user[0].image.url,
          email: user[0].email
        }
        render json: {
            status: 200,
            referral_count: registered_referrals.length,
            registered_referrals: JSON.parse(registered_referrals.to_json),
            user: JSON.parse(user_info.to_json)
          }
      else
        render json: {status: 400, error: "User not found for auth_token #{params[:auth_token]}"}
      end
    rescue => e
      render json: { status: 500 , error: "Something went wrong. Please try again later.", error_details: e.message}
    end
  end

  # It retrieves all the users information who interacted with current user.
  def get_buddies
    buddies = {}
    @user.users_with_interaction.each do |user|
      buddies[user.id] = user.info
    end
    render json: {status: 200, buddies: buddies, buddy_count: buddies.length}
  end

  # Used in chat conversation to send messages.
  def send_message
    user_ids = params[:conversation_id].blank? ? params[:user_ids] : []
    conversation = ChatConversation.find_or_create_conversation_for(@user, user_ids, params[:conversation_id])
    if params[:typing].try(:to_bool)
      conversation.trigger_typing_event_except(@user, params[:typing])
    else
      conversation.reply(params[:message])
    end
    render json: {status: 200, conversation_id: conversation.id}
  end

  # Get all chat converstion of current user.
  def get_conversations
    params[:per_page] ||= 20
    conversations = []
    @user.conversations.with_messages.individual.includes(:active_users).page(params[:page]).per(params[:per_page]).each do |conversation|
      conversations << conversation.attributes.merge(related_user: (conversation.members.except_user(@user)).first.info)
    end
     if conversations
       render json: {status: 200, conversations: conversations}
     else
       render json: {status: 400, error: "No chat conversation found."}
     end
  end

  # Get recent chat converstion of current user.
  def get_recent_conversations
    conversations = []
    @user.conversations.with_messages.individual.includes(:active_users).order('chat_conversations.updated_at DESC').limit(5).each do |conversation|
      conversations << conversation.attributes.merge(related_user: (conversation.members.except_user(@user)).first.info)
    end
     if conversations
       render json: {status: 200, conversations: conversations}
     else
       render json: {status: 400, error: "No chat conversation found."}
     end
  end

  # Used to get messages of conversation Id passed.
  def get_messages
    params[:per_page] ||= 20
    conversation = @user.conversations.with_messages.individual.includes(:active_users).find(params[:conversation_id])
    if conversation
      render json: {status: 200, messages: conversation.messages.order('id DESC').page(params[:page]).per(params[:per_page])}
    else
      render json: {status: 400, error: "No message found for the conversation id: #{params[:conversation_id]}"}
    end
  end

  # Used to create channel for chat conversation of users.
  def pusher_auth
    if @user and params[:type]
      channel_name = case params[:type]
        when 'presence'
          'presence-user'
        when 'private'
          "private-user-#{@user.id}"
      end
      client = ActsAsTenant.current_tenant.pusher_configuration.client
      response = client[channel_name].authenticate(params[:socket_id], user_id: @user.id)
      render json: response
    else
      render status: 403, text: 'Forbidden'
    end
  end

  # Find and add user as friend of current user.
  def add_friend
    if params[:user_id]
      user = User.find(params[:user_id])
      unless @user.is_favorite_users?(user)
        @user.mark_favorite(user)
        render json: {status: 200, success: "#{user.name} became your friend."}
      else
        render json: {status: 401, notice: "#{user.name} is already your friend."}
      end
    else
      render json: {status: 400, errors: "Please provide valid user id"}
    end
  end

  # Find and remove friend of current user.
  def remove_friend
    if params[:user_id]
      user = User.find(params[:user_id])
      if @user.is_favorite_users?(user)
        @user.unmark_favorite(user)
        render json: {status: 200, success: "#{user.name} removed from your friend's list."}
      else
        render json: {status: 401, notice: "#{user.name} is not in your friend's list."}
      end
    else
      render json: {status: 400, errors: "Please provide valid user id"}
    end
  end

end
