class Users::ShixunService
  attr_reader :user, :params

  def initialize(user, params)
    @user   = user
    @params = params
  end

  def call
    shixuns = category_scope_shixuns

    shixuns = user_policy_filter(shixuns)

    custom_order(shixuns, params[:sort_by], params[:sort_direction])
  end

  private

  def category_scope_shixuns
    case params[:category]
    when 'study' then
      user.study_shixuns
    when 'manage' then
      user.shixuns
    else
      ids = user.study_shixuns.pluck(:id) + user.shixuns.pluck(:id)
      Shixun.where(id: ids)
    end
  end

  def status_filter(relations)
    case params[:category]
    when 'study' then
      study_shixun_status_filter(relations)
    when 'manage' then
      manage_shixun_status_filter(relations)
    else
      relations
    end
  end

  def user_policy_filter(relations)
    # 只有自己或者管理员才有过滤筛选及查看全部状态下实训功能
    if self_or_admin?
      relations = relations.where.not(status: -1)
      status_filter(relations)
    else
      relations.where(status: [2, 3], hidden: false)
    end
  end

  def self_or_admin?
    User.current.id == user.id || User.current.admin?
  end

  def study_shixun_status_filter(relations)
    status = case params[:status]
             when 'passed'     then 1
             when 'processing' then 0
             end
    relations = relations.where(myshixuns: { status: status }) if status
    relations
  end

  def manage_shixun_status_filter(relations)
    status = case params[:status]
             when 'editing'   then 0
             when 'applying'  then 1
             when 'published' then 2
             when 'closed'    then 3
             end
    relations = relations.where(status: status) if status
    relations
  end

  def custom_order(relations, sort_by, sort_direction)
    sort_by        = sort_by&.downcase
    sort_direction = sort_direction&.downcase

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

    if sort_by == 'language'
      return relations.left_joins(:tag_repertoires).order("tag_repertoires.name #{sort_direction}")
    end

    case params[:category]
    when 'study' then
      relations.order("myshixuns.updated_at #{sort_direction}")
    when 'manage' then
      relations.order("shixuns.updated_at #{sort_direction}")
    else
      relations.order("shixuns.created_at #{sort_direction}")
    end
  end
end