class Api::V1::Projects::Pulls::Journals::ListService < ApplicationService
  include ActiveModel::Model
  
  attr_reader :project, :pull_request, :keyword, :review_id, :need_respond, :state, :parent_id, :path, :is_full, :sort_by, :sort_direction, :user
  attr_accessor :queried_journals

  validates :sort_by, inclusion: {in: Journal.column_names, message: '请输入正确的SortBy'}
  validates :sort_direction, inclusion: {in: %w(asc desc), message: '请输入正确的SortDirection'}
  validates :need_respond, inclusion: {in: [true, false], message: '请输入正确的NeedRespond'}, allow_nil: true 
  validates :is_full, inclusion: {in: [true, false], message: '请输入正确的IsFull'}
  validates :state, inclusion: {in: %w(opened resolved disabled)}, allow_nil: true 

  def initialize(project, pull_request, params, user)
    @project = project 
    @pull_request = pull_request
    @keyword = params[:keyword]
    @review_id = params[:review_id]
    @need_respond = ActiveModel::Type::Boolean.new.cast(params[:need_respond])
    @state = params[:state]
    @parent_id = params[:parent_id]
    @sort_by = params[:sort_by] || 'created_on'
    @sort_direction = params[:sort_direction] || 'asc'
    @is_full = ActiveModel::Type::Boolean.new.cast(params[:is_full]) || false
    @path = params[:path]
    @user = user
  end

  def call 
    raise Error, errors.full_messages.join(",") unless valid?
    journal_query_data 

    queried_journals
  end 

  private
  def journal_query_data
    journals = @pull_request.journals
    if !is_full 
      if parent_id.present? 
        journals = journals.where(parent_id: parent_id)
      else
        journals = journals.parent_journals
      end
    end

    journals = journals.where(review_id: review_id) if review_id.present?
    journals = journals.where(need_respond: need_respond) if need_respond.present?
    journals = journals.where(state: state) if state.present?
    journals = journals.where(path: path) if path.present?

    q = journals.ransack(notes_cont: keyword)
    scope = q.result.includes(:user, :resolveer, :children_journals, review: [:reviewer, pull_request: :issue])
    scope = scope.order("journals.#{sort_by} #{sort_direction}")

    @queried_journals = scope
  end
end