class RequestLogCollection
  class Item
    attr_reader :document, :collection
    private :document, :collection

    def initialize(document, collection) # FIXME: instead of injecting collection, inject the app
      @document   = document
      @collection = collection
    end

    def app
      collection.cached_apps[application_id]
    end

    document_attrs = %w(application_id log usage)
    log_attrs      = %w(code request response)

    document_attrs.each { |m| define_method(m) { document[m] } }
    log_attrs.each { |m| define_method(m) { log[m] } }

    def timestamp
      I18n.l(Time.parse(document['timestamp'.freeze]).in_time_zone)
    end

    def as_json(options = {})
      {code: code,
       application_id: application_id,
       usage: usage,
       request: request,
       response: response,
       timestamp: timestamp.as_json,
       app: app.as_json(root: false, only: [:name, :id], include: [account: {only: [:org_name, :id]}])}
    end
  end

  attr_reader :service, :cached_apps

  def initialize(service, documents)
    @service   = service
    @documents = documents
    @app_ids   = []
  end

  def logs
    unless @logs
      fetch_items
      preload_apps
    end
    @logs
  end

  delegate :total, to: :documents

  private

  attr_reader :documents, :app_ids

  def fetch_items
    @logs = documents.each_with_object([]) do |log, memo|
      item     = Item.new(log[:body], self)
      app_ids << item.application_id
      memo    << item

      memo
    end
  end

  def preload_apps
    @cached_apps = cinstances_with_ids(app_ids).index_by(&:application_id)
  end

  def cinstances_with_ids(ids = [])
    service.cinstances.where(application_id: ids).includes(:user_account)
  end
end
