class ApplicationController < ActionController::Base
  require "pusher"
  protect_from_forgery :except => [:pusher_auth, :show_past_conversation, :parse_offline_chat_reply]

  #rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found
  rescue_from Faraday::Error::ConnectionFailed, :with => :balanced_timeout

  prepend_before_filter :find_university_by_subdomain
  helper_method :set_current_user_linkedin, :subdomain_present?, :render_action_in_other_controller
  before_filter :set_current_user, :check_for_previous_confirmed_sessions
  skip_before_filter :set_current_user, :only => :pusher_ol
  before_filter :set_default_metatags
  before_filter :redirect_to_admin_dashboard
  before_filter :find_current_video_sessions
  helper_method :next_profile_question
  before_filter :log_requests_in_db, :except => [:pusher_auth, :minimize, :maximize, :close]

  # To find ongoing video sessions
  def find_current_video_sessions
    if logged_in? and !current_user.super_admin?
      @video_sessions = current_user.related_sessions.video_sessions.ongoing_sessions.includes(:video_session_room)
    end
  end

  # To redirect page on to admin dashboard
  def redirect_to_admin_dashboard
    if subdomain_present? and current_user and current_user.super_admin?
      redirect_to admin_path(subdomain: false)
    end
  end

  # To find university by their subdomain
  def find_university_by_subdomain
    if subdomain_present?
      ActsAsTenant.current_tenant = University.find_by!(subdomain: request.subdomains.last)
      unless ActsAsTenant.current_tenant
        redirect_to root_url(subdomain: false)
      end
    else
      ActsAsTenant.current_tenant = nil
    end
  end

  # To initialize group chat
  def init_chat_for(group)
    @conversation = group.chat_conversation || group.create_chat_conversation(grouped: true)
    @conversation.init_chat_for(current_user)
    current_user.chat_activities.find_or_create_by(chat_conversation: @conversation)
  end

  # To initialize chat with specific user
  def init_chat_with(user_ids = [], conversation_id=nil)
    @conversation = ChatConversation.find_or_create_conversation_for(current_user, user_ids, conversation_id)
    if @conversation
      @conversation.init_chat_for(current_user)
      current_user.chat_activities.find_or_create_by(chat_conversation: @conversation)
    end
  end

  # If there is confirmed session but not paid than forcefully redirect user to dashboard page
  def check_for_previous_confirmed_sessions
    if logged_in? && current_user.previous_confirmed_sessions.exists?
      request.xhr? ? (redirect_via_turbolinks_to dashboard_path) : (redirect_to dashboard_path)
    end
  end

  # To set current user
  def set_current_user
    User.current = current_user
  end

  # To set default metatages
  def set_default_metatags
    tags = {
      'title' => ActsAsTenant.current_tenant.try(:name) || "-----", 
      'time-zone' => Time.zone.name,
      'current-date' => Date.today_in_time_zone.to_s(:db)
    }
    if ActsAsTenant.current_tenant and ActsAsTenant.current_tenant.pusher_configuration.try(:api_key)
      tags.merge!('pusher-api-key' => ActsAsTenant.current_tenant.pusher_configuration.try(:api_key))
    end
    if logged_in? and current_user.is_registration_completed? and ActsAsTenant.current_tenant and ActsAsTenant.current_tenant.pusher_configuration.try(:enabled)
      tags.merge!({
        'current-user-id' => current_user.try(:id)
      })
    end
    gon.meta_tags = set_meta_tags(tags)
  end

  # Redirect and show alert when the user is not authenticated
  def not_authenticated
    respond_to do |format|
      format.js
      format.html { redirect_to root_url, :alert => "First login to access this page." }
    end
  end

  # Raise exception if subdomain not found
  def require_subdomain
    if request.subdomain.blank? or request.subdomain.match(/\Awww\z/i)
      raise DatabaseNotFound, "Cannot find tenant #{environmentify(tenant)}"
    end
  end

  # To check if subdomain is present
  def subdomain_present?
    request.subdomain.present? and !request.subdomain.match(/\Awww\z/i)
  end

  # To get next profile question
  def next_profile_question(current_question = 0)
    return 'complete' if cookies[:profile_question]
    current_question = 0 if current_question >= User::PROFILE_QUESTION.size
    User::PROFILE_QUESTION[current_question..-1].each do |attribute|
      attr1, attr2 = attribute.split(':', 2)
      if attr2
        return "#{attr1}/#{attr2}" if current_user.send(attr1).blank?
        if attr1 == "profile_image"
         return "#{attr1}/#{attr2}" if current_user.send(attr1).send(attr2).blank?
        else
          return "#{attr1}/#{attr2}" if current_user.send(attr1).first.send(attr2).blank?
        end
      else
        unless current_user.student? && attr1 == 'rate'
          return attr1 if current_user.send(attr1).blank?
        end
      end
    end
    return 'complete'
  end

  protected

  def user_class
    session[:super_admin] ? Admin : super
  end

  # If current user not completed with registration than go to the next profile step
  def check_registration
    if current_user and !current_user.is_registration_completed?
      redirect_to edit_profile_path(current_user.next_profile_step)
    end
  end

  # show error 404 "not found"
  def render_404
    respond_to do |format|
      format.html { render :file => "#{Rails.root}/public/404", :layout => false, :status => :not_found }
      format.xml  { head :not_found }
      format.any  { head :not_found }
    end
  end

  private

  def require_tutor
    unless current_user && current_user.tutor?
      redirect_to root_path
    end
  end

  def require_student_or_tutor
    redirect_to root_path and return unless logged_in?
    unless current_user.tutor? || current_user.student?
      redirect_to admin_path and return if current_user.admin?
    end
  end

  def record_not_found
    flash[:alert] = "Sorry, this page does not exist, please contact #{Configurations::General.default_mail_from} if you have any trouble accessing the site"
    redirect_to root_path
  end

  def balanced_timeout
    flash[:alert] = "Sorry, Please try again."
    redirect_to :back
  end

  def log_requests_in_db
    begin
      @parameter_filter ||= ActionDispatch::Http::ParameterFilter.new Rails.application.config.filter_parameters
      parameters = @parameter_filter.filter(params.except("action", "controller")).except('utf8')
      RequestLog.create!(user_id: current_user.try(:id), controller: params[:controller], action: params[:action], ip_address: request.remote_ip, url: request.url, parameters: parameters, created_at: Time.now.in_time_zone)
    rescue => e
      log = Logger.new("log/activity.log")
      log.debug "Activity recording failed due to #{e.message}."
    end
  end

end
