module Dunlop::WorkflowInstanceBatchModel
  extend ActiveSupport::Concern

  included do
    include Dunlop::ProcessIdentification

    has_many :workflow_instances, inverse_of: :workflow_instance_batch
  end

  def workflow_instance_class
    self.class.name.sub(/WorkflowInstanceBatch/, 'WorkflowInstance').constantize
  end

  def workflow_step_map(user)
    workflow_instance_class.workflow_step_classes.map do |workflow_step_class|
      #base_scope = workflow_step_class.joins(:workflow_instance).where{ workflow_instance.workflow_instance_batch_id == my{id} } #squeel
      base_scope = workflow_step_class.joins(:workflow_instance).where(workflow_instances: {workflow_instance_batch_id: id})
      #base_scope = base_scope.where.not(workflow_instances: {service_provider_id: nil}).where(workflow_instances: {service_provider_id: user.service_provider_id}) unless user.admin?
      #base_scope = base_scope.where(workflow_instances: {service_provider_id: user.service_provider_id, archived: false}) if user.service_provider_id.present?
      [workflow_step_class,  base_scope]
    end.to_h
  end

  module ClassMethods
    def active
      all
    end

    def for_select
      active.map{|mb| [mb.presentation_name, mb.id]}
    end

    # return a mapping for each batch containing the state counts for all
    # the workflow step states. This is a performance implementation heavily
    # reducing the time (queries) for large amount of batches
    def workflow_step_map(user, options = {})
      #NOTE: do not cache this method!
      batch_ids = pluck(:id)
      workflow_instance_class = self.name.sub(/WorkflowInstanceBatch/, 'WorkflowInstance').constantize
      workflow_instance_class.workflow_step_classes.map.with_object(Hash.new{|h, k| h[k] = {}}) do |klass, hash|
        step_counts_scope = klass.joins(:workflow_instance).where(workflow_instances: {workflow_instance_batch_id: batch_ids})
        if options[:archived].present?
          step_counts_scope = step_counts_scope.where.not(workflow_instances: {archived_at: nil})
        else
          step_counts_scope = step_counts_scope.where(workflow_instances: {archived_at: nil})
        end
        step_counts = step_counts_scope.group("#{klass.table_name}.state", 'workflow_instances.workflow_instance_batch_id').count
        step_counts.each do |(state, batch_id), count|
          hash[batch_id][klass] ||= Hash.new{|h, k| h[k] = {}}
          hash[batch_id][klass][state] = count
        end
      end
    end
  end
end
