class Supplier
  module Counters
    extend ActiveSupport::Concern

    def reset_counters!
      spec = Order.by_supplier_id_and_state(startkey: [id], endkey: [id, {}], reduce: true, group_level: 2)
      self.class.reset_order_counters_with_spec spec
    end

    def increment_orders_in_process_count!
      Qwaiter::Counter.incr orders_in_process_counter_key
    end

    def increment_orders_placed_count!
      Qwaiter::Counter.incr orders_placed_counter_key
    end

    def decrement_orders_in_process_count!
      Qwaiter::Counter.decr orders_in_process_counter_key
    end

    def decrement_orders_placed_count!
      Qwaiter::Counter.decr orders_placed_counter_key
    end

    def orders_in_process_count
      Qwaiter::Counter.get orders_in_process_counter_key
    end

    def orders_placed_count
      Qwaiter::Counter.get orders_placed_counter_key
    end


    def active_order_count
      orders_in_process_count + orders_placed_count
    end

    def orders_in_process_counter_key
      self.class.orders_in_process_counter_key(id)
    end

    def orders_placed_counter_key
      self.class.orders_placed_counter_key(id)
    end

    module ClassMethods

      def orders_in_process_counter_key(id)
        "supplier_counter:#{id}:orders_in_process"
      end

      def orders_placed_counter_key(id)
        "supplier_counter:#{id}:orders_placed"
      end

      def reset_counters!
        # Set all known counters to zero
        Qwaiter::Couchbase.flush_counters!

        Qwaiter::Counter.connection.flush if Qwaiter::Counter.connection.respond_to?(:flush)

        spec = Order.by_supplier_id_and_state(reduce: true, group_level: 2)
        reset_order_counters_with_spec spec
      end

      def reset_order_counters_with_spec(spec)
        # taken from the couch_potato source since we want a model/custom mix here (hmmmm, something that should be fixed in the couchbase version)
        view_spec = {spec.view_name => { map: spec.map_function, reduce: spec.reduce_function} }
        list_spec = spec.list_name.nil? ? nil : {spec.list_name => spec.list_function}
        lib_spec = nil # do not yet know meaning of this param
        query_view = CouchPotato::View::ViewQuery.new(
          database.couchrest_database,
          spec.design_document,
          view_spec,
          list_spec,
          lib_spec,
          spec.language
        )
        results = query_view.query_view!(spec.view_parameters)
        Array.wrap(results['rows']).each do |result|
          supplier_id, state = result['key']
          case state
          when 'placed' then Qwaiter::Counter.set orders_placed_counter_key(supplier_id), result['value']
          when 'active' then Qwaiter::Counter.set orders_in_process_counter_key(supplier_id), result['value']
          end
        end
      end
    end
  end
end
