class Item < ActiveRecord::Base

  CSV_COL = {
    :code => 0,
    :input_price => 1,
    :list_price => 2,
    :decoration => 3
  }

  belongs_to :unit
  has_many :multi_media_descriptions
  belongs_to :sub_category
  belongs_to :supplier
  belongs_to :brand
  belongs_to :delivery_time_estimation


  validates_presence_of :name, :description, :list_price, :current_input_price, :tags, :unit_id, :code, :sub_category_id, :weight, :supplier_id
  validate :we_must_earn_money

  def self.items_to_order
    items_raw = Item.find_by_sql(%Q{
                                   select s.id as supplier_id, i.code as code, i.name as name, sum(iic.count) amount, i.current_input_price
                                   from carts c
                                   left join item_in_carts iic on iic.cart_id = c.id
                                   left join items i on i.id = iic.item_id
                                   left join suppliers s on i.supplier_id = s.id
                                   where c.confirmed and not (c.packed or c.delivered)
                                   group by s.id, i.name, i.code, i.current_input_price
                                   order by s.name, amount desc;
    })

    items_sorted = {}
    suppliers_sorted = {}

    items_raw.each do |item|
      items_sorted[item.supplier_id] ||= []
      suppliers_sorted[item.supplier_id] ||= item.supplier
      items_sorted[item.supplier_id] << item
    end

    report_items = []

    complete_sum = 0

    suppliers_sorted.each_pair do |key, value|

      rep_sec = OpenStruct.new # report section
      rep_sec.supplier = value
      rep_sec.items = items_sorted[key]
      rep_sec.sum_amount = rep_sec.items.reduce(0) do |sum, item|
        sum + (item.current_input_price * item.amount)
      end
      complete_sum += rep_sec.sum_amount

      report_items << rep_sec
    end

    full_report = OpenStruct.new
    full_report.sections = report_items
    full_report.full_sum = complete_sum

    return full_report
  end


  def self.orders_to_confirm
    items_raw = Item.find_by_sql(%Q{
                                   select dd.*, c.id as order_id,i.code as code, i.name as item, iic.count as amount , i.list_price, iic.count * i.list_price as sum_price
                                   from carts c
                                   left join delivery_destinations dd on c.delivery_destination_id = dd.id
                                   left join item_in_carts iic on iic.cart_id = c.id
                                   left join items i on i.id = iic.item_id

                                   where c.ordered and not(c.canceled_on_check or c.canceled_on_delivery or c.confirmed or c.packed or c.delivered)
                                   order by
                                   c.created_at, iic.created_at;
    })

    items_sorted = {}

    items_raw.each do |item|
      items_sorted[item.phone] ||=  []
      items_sorted[item.phone] << item
    end

    sections = []
    complete_sum = 0

    items_sorted.each_pair do |key,values|
      section = OpenStruct.new
      section.delivery_destination = values.first
      section.sum_amount = 0
      section.items = []
      values.each do |item|
        section.sum_amount += item.sum_price
        complete_sum += item.sum_price
        section.items << item
      end
      sections << section
    end
    full_report = OpenStruct.new
    full_report.sections = sections
    full_report.full_sum = complete_sum

    return full_report
  end

  def self.update_prices(path)
    nonexistent_codes = []

    Item.transaction do
      CSV.foreach(path) do |row|
        code = row[CSV_COL[:code]].strip
        item = Item.find_by_code(code)
        if item.nil?
          nonexistent_codes << code
        else
          item.current_input_price = row[CSV_COL[:input_price]]
          item.list_price = row[CSV_COL[:list_price]]
          item.decoration = row[CSV_COL[:decoration]]
          item.save!
        end
      end
    end
    puts "Nonexistent codes: "
    puts nonexistent_codes.join("\n")
  end

  def we_must_earn_money
    if list_price.to_f <= current_input_price.to_f
      errors[:list_price] << "#{code} Ulazna cijena veca od izlazne"
    end
  end


end
