class Projects::ListQuery < ApplicationQuery
  include CustomSortable

  attr_reader :params, :current_user_id

  sort_columns :updated_on, :created_on, :forked_count, :praises_count, default_by: :updated_on, default_direction: :desc, default_table: 'projects'

  def initialize(params, current_user_id=nil)
    @params = params
    @current_user_id = current_user_id
  end

  def call
    collection = Project.secret_and_visible
    # 增加私有组织中项目过滤
    collection = collection.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id")
                           .where("organization_extensions.visibility is null or organization_extensions.visibility in (0,1)")
                           .where("projects.user_id > 0")
    collection = Project.all if params[:admin_token] =="7917908927b6f1b792f2027a08a8b24a2de42c1692c2fd45da0dee5cf90a5af5" && User.find_by(id: @current_user_id).present? && User.find_by(id: @current_user_id).admin?
    collection = filter_projects(collection)

    sort = params[:sort_by] || "updated_on"
    sort_direction = params[:sort_direction] || "desc"

    # collection = optimize_sorting(collection, sort) if params[:category_id].present?
    custom_sort(collection, sort, sort_direction)

    # scope = scope.reorder("projects.#{sort} #{sort_direction}")
    # scope
  end

  def filter_projects(collection)
    collection = by_pinned(collection)
    collection = by_recommend(collection)
    collection = by_search(collection) if params[:search].present?
    collection = by_project_type(collection)
    collection = by_project_category(collection)
    collection = by_project_language(collection)
    collection = by_project_topic(collection)
    collection = exclude_fork(collection)
    collection
  end

  def main_collection
    collection = Project.visible.where(status: 1)
    # 增加私有组织中项目过滤
    collection = collection.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id")
                           .where("organization_extensions.visibility is null or organization_extensions.visibility in (0,1)")
                           .where("projects.user_id > 0")
    collection
  end

  def by_search(items)
    items.by_name_or_identifier(params[:search]).or(items.where(user_id: Owner.like(params[:search]).pluck(:id)))
  end
  
  def by_project_type(items)
    items.with_project_type(params[:project_type])
  end

  def by_project_category(items)
    items.with_project_category(params[:category_id])
  end

  def by_project_language(items)
    items.with_project_language(params[:language_id])
  end
  
  def by_pinned(items)
    (params[:pinned].present? && params[:category_id].present?) ? items.pinned : items
  end

  def by_project_topic(items)
    if params[:topic_name].present?
      items.with_project_topic_name(params[:topic_name].to_s.split(","))
    else
      items.with_project_topic(params[:topic_id])
    end
  end

  # 优化排序
  def optimize_sorting(relations, sort_by)
    if sort_by == "updated_on"
      relations.where("projects.updated_on>'2010-01-01'")
    elsif sort_by == "created_on"
      relations.where("projects.created_on>'2010-01-01'")
    elsif sort_by == "forked_count"
      relations.where("projects.forked_count>=0")
    elsif sort_by == "praises_count"
      relations.where("projects.praises_count>=0")
    else
      relations
    end
  end

  def by_recommend(items)
    params[:recommend].to_s == "true" ? items.where(recommend: true) : items
  end

  def exclude_fork(items)
    return items if params[:exclude_forked].blank?
    params[:exclude_forked].to_s == "true" ? items.where("forked_from_project_id is null") : items.where("forked_from_project_id is not null")
  end

end
