module Dunlop::WorkflowInstanceModel
  extend ActiveSupport::Concern

  included do
    include Dunlop::WorkflowInstanceModel::StateMachineHandling
    include Dunlop::WorkflowInstanceModel::WorkflowStepHandling
    include Dunlop::WorkflowInstanceModel::ArchivedHandling
    include Dunlop::WorkflowInstanceModel::CategorizationAndResetHandling
    include Dunlop::ProcessIdentification
    include Dunlop::CollectionLookup
    @scenario_workflow_step_names = []

    belongs_to :workflow_instance_batch, inverse_of: :workflow_instances, optional: true
  end

  def is_planned?
    respond_to?(:plan_date) ? plan_date.present? : false
  end

  module ClassMethods
    attr_reader :scenario_names
    def setup_scenarios(scenario_names)
      @scenario_names = scenario_names
    end

    def activate_dunlop!
      possible_workflow_step_names.each do |step_name|
        has_one step_name, dependent: :destroy #, inverse_of: :workflow_instance
      end
      #raise "No scenarios defined!, define scenarios using: setup_scenarios :scenario1, :other_scenario" unless @scenario_names
      #scenario_classes # this will raise if not all of them can be constantized
    end

    # Add include statements to the scope for including workflow_instance
    # displays for the index action
    def including_relations
      includes(*scenario_workflow_step_names, :workflow_instance_batch)
    end

    def scenario_classes
      scenario_names.map{|scenario_name| "WorkflowInstance::#{scenario_name.to_s.classify}".constantize }
    end

    def scope_for(user, options = {})
      scope = options[:all] ? all : (options[:archived] ? archived : active)
      #scope = scope.where(service_provider_id: user.service_provider_id) if user.service_provider_id.present?
      scope
    end

    def available_bucket_names
      distinct.pluck(:bucket).map(&:presence).compact
    end

    def batch_class
      @batch_class ||= name.sub('WorkflowInstance', 'WorkflowInstanceBatch').safe_constantize
    end

    # Mainly used in development stage from console or as a post migration
    # step. This adds workflow_steps that should be there based on the
    # configuration but are missing in the database
    def add_missing_workflow_steps
      includes(*possible_workflow_step_names).find_in_batches do |workflow_instances|
        transaction do
          workflow_instances.each do |workflow_instance|
            workflow_instance.setup_workflow_steps
            workflow_instance.save
          end
        end
      end
    end
  end
end
