class Users::QuestionBanksController < Users::BaseController
  before_action :check_query_params!
  before_action :check_user_permission!

  def index
    service = Users::QuestionBankService.new(observed_user, query_params)
    question_banks = service.call

    @count          = question_banks.count
    @course_lists   = service.course_lists
    @question_banks = paginate(question_banks.includes(:user, :course_list), special: true)

    load_question_banks_solve_count   # for solve n + 1
  end

  private

  def load_question_banks_solve_count
    question_bank_ids = @question_banks.map(&:id)
    @solve_count_map =
      case params[:category]
      when 'common', 'group' then
        StudentWork.where(is_delete: false, work_status: [1, 2, 3]).joins(:homework_common)
          .where(homework_commons: { homework_bank_id: question_bank_ids })
          .group('homework_commons.homework_bank_id').count
      when 'exercise' then
        ExerciseUser.joins(:exercise)
          .where(commit_status: 1, exercises: { exercise_bank_id: question_bank_ids })
          .group('exercises.exercise_bank_id').count
      when 'poll' then
        PollUser.joins(:poll).where(polls: { exercise_bank_id: question_bank_ids })
          .group('polls.exercise_bank_id').count
      when 'gtask' then
        GraduationWork.has_committed.joins(:graduation_task)
          .where(graduation_tasks: { gtask_bank_id: question_bank_ids })
          .group('graduation_tasks.gtask_bank_id').count
      when 'gtopic' then
        StudentGraduationTopic.joins(:graduation_topic)
          .where(gtopic_banks: { gtopic_bank_id: question_bank_ids }).where('status != 0')
          .group('gtopic_banks.gtopic_bank_id').count
      end
  end

  def query_params
    params.permit(:type, :category, :course_list_id, :sort_by, :sort_direction)
  end

  def check_query_params!
    params[:type] = 'personal' if params[:type].blank? || !%w(personal publicly).include?(params[:type])

    if params[:category].blank? || !%w(common group exercise poll gtask gtopic).include?(params[:category])
      params[:category] = 'common'
    end

    if params[:sort_by].blank? || !%w(updated_at name contributor).include?(params[:sort_by])
      params[:sort_by] = 'updated_at'
    end

    if params[:sort_direction].blank? || !%w(desc asc).include?(params[:sort_direction])
      params[:sort_direction] = 'desc'
    end
  end

  def check_user_permission!
    return if User.current.admin? || (observed_logged_user? && read_question_bank_permission?)

    render_forbidden
  end

  def read_question_bank_permission?
    params[:type] == 'personal' ? User.current.is_teacher? : User.current.certification_teacher?
  end
end