class InventoryDefinition < ApplicationRecord

  has_many :stock_journals
  has_one :menu_item_instance, foreign_key: "item_instance_code", primary_key: "item_code"

  scope :active, -> {where(:is_active => true)}

  def self.calculate_product_count(saleObj=nil,saleobj_after_req_bill=nil)
    # check_sj = StockJournal.where('item_code=?', item.item_instance_code).order("id DESC").first
    logger.debug 'saleObj<<<<<<<<<<<<<<<<<<<<<<<<<<<'
    logger.debug saleObj.sale_items.to_json
    if !saleObj.nil?
      saleObj.sale_items.each do |item|
        found, inventory_definition = find_product_in_inventory(item)
        if found
          check_balance(item,inventory_definition)
        end
      end
    else
      saleobj_after_req_bill.each do |item|
        found, inventory_definition = find_product_in_inventory(item)
        if found
          check_balance(item,inventory_definition)
        end
      end
    end
  end


  def self.find_product_in_inventory(item)
   if product = InventoryDefinition.find_by_item_code(item.item_instance_code)
      if stock_check_item = StockCheckItem.find_by_item_code(item.item_instance_code)
        return true, product
      end
    end
  end

  def self.check_balance(item, inventory_definition) # item => saleItemOBj

   stock = StockJournal.where("item_code=?", item.item_instance_code).order("id DESC").first
   unless stock.nil?
     modify_balance(item, stock, inventory_definition)
   else
     StockJournal.add_to_journal(item.item_instance_code, item.qty, 0, "out of stock", inventory_definition, item.id, StockJournal::SALES_TRANS)
   end
  end

  def self.modify_balance(item, stock, inventory_definition) #saleitemObj
    check_item = StockCheckItem.where('item_code=?', item.item_instance_code).order("id DESC").first
    if item.qty.to_i >= 0
      qty = item.qty - item.qty_was
      if !item.id_was.nil?
        remark = "edit"
      elsif stock.balance.to_i >= qty
        puts ">> stock is greater than order qty"
        remark = "ok"
      else
        puts " << stock is less than order qty"
        remark = "out of stock"
      end
    else # item.qty < 0
      qty = item.qty
      remark = "void"
    end
    if item.is_a? OrderItem
      trans_type = StockJournal::ORDER_TRANS
    elsif item.is_a? SaleItem
      trans_type = StockJournal::SALES_TRANS
    end
    # StockJournal.add_to_journal(instance_code, qty, stock.balance, remark, inventory_definition, item.id, trans_type)
    StockJournal.add_to_journal(item.item_instance_code, qty, stock.balance, remark, inventory_definition, item.id, trans_type)
    check_item.different = check_item.different - qty
    check_item.save
  end

  def self.search_by_category(cat_id)
     inventory_definitions =   InventoryDefinition.select("inventory_definitions.*,
                 mi.name as item_name,mii.item_instance_name as instance_name," +
                 "mi.item_code as item_code,mii.item_instance_code as instance_code," +
                "mc.name as menu_category_name,mc.id as menu_category_id ")
                .joins("JOIN menu_item_instances mii ON mii.item_instance_code = inventory_definitions.item_code" +
                     " JOIN menu_items mi ON mi.id = mii.menu_item_id" +
                     " JOIN menu_categories mc ON mc.id = mi.menu_category_id ")
                .where("mc.id=#{cat_id}")
                .group("mi.menu_category_id,inventory_definitions.item_code")
                .order("mi.menu_category_id desc")
  end

  def self.get_by_category(filter)
    least_stock = StockJournal.select(:inventory_definition_id, :credit, :debit, :balance)
                  .joins("JOIN (
                    #{StockJournal.select("item_code, MAX(created_at) created_at").group(:item_code).to_sql}) last_stock_journals
                    ON last_stock_journals.item_code = stock_journals.item_code
                    AND last_stock_journals.created_at = stock_journals.created_at").to_sql

    inventory_definitions = InventoryDefinition
                .select("inventory_definitions.*,
                  stock_journals.credit as credit,
                  stock_journals.debit as debit,
                  stock_journals.balance as balance,
                  accounts.title as account_name,
                  menu_items.name as item_name,
                  menu_item_instances.item_instance_name as instance_name,
                  menu_categories.name as menu_category_name,
                  menu_categories.id as menu_category_id")
                .joins("LEFT JOIN (#{least_stock}) stock_journals on stock_journals.inventory_definition_id = inventory_definitions.id")
                .joins(menu_item_instance: { menu_item: [:menu_category, :account]})
                .where("inventory_definitions.item_code LIKE :filter OR inventory_definitions.min_order_level LIKE :filter
                  OR inventory_definitions.max_stock_level LIKE :filter OR stock_journals.balance LIKE :filter OR menu_items.name LIKE :filter
                  OR menu_item_instances.item_instance_name LIKE :filter OR menu_categories.name LIKE :filter", filter: "%#{filter}%")
                .group("menu_items.menu_category_id, inventory_definitions.item_code")
                .order("balance asc, menu_items.name asc, accounts.title desc, menu_items.menu_category_id desc")
  end

end
