require 'csv'
class EasyEntityCsvImport < EasyEntityImport

  attr_reader :csv

  def import_format
    :csv
  end

  def process_preview_file
    @csv ||= CSV.parse_line(@file || self.get_file)
    @csv
  end

  def import_importer
    set_variables
    super
  end

  def get_csv
    # @xml ||= Nokogiri::XML.parse(@file && @file.read || self.get_file)
    # @xml
  end

  def get_available_entity_types
    %w(EasyContactGroup Project EasyInvoiceLineItem EasyMoneyOtherRevenue EasyCrmCase)
  end

  def import(file)
    set_variables unless @variables_sets
    CSV.new(file, :headers => true).each_with_index do |line, index|
      iid = (@xid && line[@xid.source_attribute.to_i].try(:strip))
      iid ||= "#{Date.today.strftime('%Y%m%d')}#{'%05d' % index}" if merge_by != 'id'
      attributes = {'custom_fields' => []}
      easy_entity_import_attributes_assignments.each do |att|
        value = att.is_custom? && att.value.presence || (line[att.source_attribute.to_i].try(:strip) || att.default_value)
        attributes = ensure_attribute_value(attributes, att, value.presence)
      end
      entity = self.entity_type.constantize.where(merge_by => iid).first_or_initialize
      entity.project_id = attributes['project_id'] if attributes['project_id']

      entity.send("#{merge_by}=", iid)

      assign_attributes(entity, attributes)

      e = build_imported_entity(iid, entity, line, attributes)
      e.entity.save(:validate => false)
      after_save_callback(e.entity, line, attributes)
      @imported_entities[iid] = e
      puts "* Importer CSV: #{iid}: #{e.entity.id} (#{e.errors.full_messages.join(', ')})"
    end

    return @imported_entities
  end

  private

  def assign_attributes(entity, attributes)
    entity.safe_attributes = attributes
    ((@associations.keys + entity.class.protected_attributes.to_a) & attributes.keys).each do |r|
      entity.send("#{r}=", attributes[r]) if entity.send(r).blank?
    end
  end

  def build_imported_entity(external_id, new_entity, csv_line, current_attributes)
    ImportedEntity.new(new_entity)
  end

  def after_save_callback(entity, csv_line, current_attributes)
    if self.template
      entity.copy(self.template)
      if entity.respond_to?(:start_date) && entity.start_date && entity.respond_to?(:update_project_entities_dates)
        day_shift = (Date.today - entity.start_date).to_i
        entity.update_project_entities_dates(day_shift)
      end
    end
  end

  def set_variables
    @xid = easy_entity_import_attributes_assignments.detect{|c| c.entity_attribute == merge_by || c.entity_attribute == 'id'}
    @imported_entities = Hash.new
    @associations = self.entity_type.constantize.reflect_on_all_associations(:belongs_to).group_by(&:foreign_key)
    @variables_sets = true
  end

  def ensure_attribute_value(attributes, att, value)
    if value && (r = @associations[att.entity_attribute]) && !value.match(/^\d+/)
      r = r.first
      v = nil
      [:named, :like].each do |find_ass|
        if r.klass.respond_to?(find_ass) && v.nil?
          v = r.klass.send(find_ass, value).first.try(:id)
        end
      end
      if v.nil?
        Rails.logger.error("Could not find association for #{att.entity_attribute} with value '#{value}'")
      else
        attributes.store(att.entity_attribute, v)
      end
    elsif att.entity_attribute.match(/cf_(\d+)/)
      @cfs_multiple ||= Hash.new; @cfs_multiple[$1] ||= CustomField.where(:id => ($1)).first
      if @cfs_multiple[$1]
        multiple = @cfs_multiple[$1].multiple?
        attributes['custom_fields'] << {'id' => $1, 'value' => value && multiple ? value.split('|') : value }
      end
    else
      attributes.store(att.entity_attribute, value)
    end

    attributes
  end

  def dependent_fields_for_entity

  end

  class ImportedEntity

    attr_accessor :entity
    attr_reader :errors

    def initialize(entity)
      @entity = entity
      @errors = entity.errors unless entity.valid?
      @errors ||= ActiveModel::Errors.new(entity)
    end

    def new_record?
      @entity.new_record?
    end

    def to_model
      @entity
    end

  end

end
require_dependency 'easy_entity_imports/easy_issue_csv_import'
require_dependency 'easy_entity_imports/easy_user_csv_import'
