class ProductCategoriesImporter
  attr_reader :errors, :supplier, :skipped

  def initialize(supplier)
    @errors = Errors.new
    @errors.importer = self
    @supplier = supplier
  end

  def import(string)
    h = YAML.load(string) rescue nil
    return errors.add 'cannot_parse_yaml' unless h
    return errors.add 'no_product_categories' unless h["product_categories"].is_a?(Array)
    categories = supplier.product_categories
    existing_products = supplier.products
    @skipped = []
    h["product_categories"].each do |product_category_spec|
      skipped << {reason: 'empty_name', type: 'product_category'} and next unless product_category_spec['name'].present?
      unless existing_category = categories.find{|pc| pc.name == product_category_spec['name']}
        existing_category = ProductCategory.new
        product_category_spec.each do |attribute, value|
          existing_category.public_send "#{attribute}=", value if existing_category.respond_to? "#{attribute}="
        end
      end
      existing_category.supplier = supplier # hard coded security
      if existing_category.valid?
        (product_category_spec['products'] || []).each do |product_spec|
          skipped << {reason: 'empty_name', type: 'product'} and next unless product_spec['name'].present?

          unless  existing_product = existing_products.find{|ep| ep.name == product_spec['name']}
            existing_product = Product.new
          end
          product_spec.each do |product_attribute, product_value|
            existing_product.public_send "#{product_attribute}=", product_value if existing_product.respond_to? "#{product_attribute}="
          end

          existing_product.supplier = supplier
          if existing_product.save
            existing_category.product_ids |= [existing_product.id]
          else
            skipped << {reason: 'could_not_save', type: 'product'}
          end

        end
        existing_category.save
      else
        skipped << {reason: 'could_not_save', type: 'product_category'}
      end
    end
    self
  end

  def success?
    errors.empty?
  end

  class Errors < Hash
    attr_accessor :importer
    def add(message)
      self[:message] = message
      importer
    end

    def message
      self[:message]
    end
  end
end
