class ApplicationController < ActionController::Base
  include BotBlocker

  # Changes to the importmap will invalidate the etag for HTML responses
  stale_when_importmap_changes

  SESSION_TIMEOUT = 3.days

  before_action :check_session_timeout

  helper_method :supported_languages, :current_user, :logged_in?, :admin?, :reviewer_or_admin?,
                :contributor_or_above?, :setup_completed?

  private

  def supported_languages
    @supported_languages ||= SupportedLanguage.where(active: true).order(:sort_order, :name)
  end

  def current_user
    return @current_user if defined?(@current_user)

    # First check session
    if session[:user_id]
      @current_user = User.find_by(id: session[:user_id])
    # Then check remember me cookie
    elsif cookies.signed[:remember_token]
      user = User.find_by_valid_remember_token(cookies.signed[:remember_token])
      if user
        session[:user_id] = user.id
        @current_user = user
      else
        # Invalid or expired remember token, clear it
        cookies.delete(:remember_token)
      end
    end

    @current_user
  end

  def check_session_timeout
    return unless logged_in?
    return if cookies.signed[:remember_token].present?

    if session[:last_activity_at].present?
      last_activity = Time.parse(session[:last_activity_at])
      if last_activity < SESSION_TIMEOUT.ago
        reset_session
        redirect_to login_path, alert: "Your session has expired. Please sign in again."
        return
      end
    end

    session[:last_activity_at] = Time.current.to_s
  end

  def logged_in?
    current_user.present?
  end

  def admin?
    logged_in? && current_user.admin?
  end

  def reviewer_or_admin?
    logged_in? && (current_user.reviewer? || current_user.admin?)
  end

  def contributor_or_above?
    logged_in?
  end

  def require_login
    unless logged_in?
      redirect_to login_path, alert: "You must be logged in to access this page."
    end
  end

  def require_admin
    unless logged_in?
      redirect_to login_path, alert: "You must be logged in to access this page."
      return
    end

    unless current_user.admin?
      redirect_to root_path, alert: "You must be an administrator to access this page."
    end
  end

  def require_reviewer
    unless reviewer_or_admin?
      redirect_to root_path, alert: "You must be a reviewer or administrator to access this page."
    end
  end

  def require_contributor
    unless contributor_or_above?
      redirect_to root_path, alert: "You must be a contributor to access this page."
    end
  end

  def setup_completed?
    SetupState.installed?
  end
end
