class Import::CategoryMapping < Import::Mapping
  class << self
    def mappables_by_key(import)
      unique_values = import.rows.map(&:category).uniq

      # For hierarchical QIF keys like "Home:Home Improvement", look up the child
      # name ("Home Improvement") since category names are unique per family.
      lookup_names = unique_values.map { |v| leaf_category_name(v) }
      categories = import.family.categories.where(name: lookup_names).index_by(&:name)

      unique_values.index_with { |value| categories[leaf_category_name(value)] }
    end

    private

      # Returns the leaf (child) name for a potentially hierarchical key.
      # "Home:Home Improvement" → "Home Improvement"
      # "Fees & Charges"        → "Fees & Charges"
      def leaf_category_name(key)
        return "" if key.blank?

        parts = key.to_s.split(":", 2)
        parts.length == 2 ? parts[1].strip : key
      end
  end

  def selectable_values
    family_categories = import.family.categories.alphabetically.map { |category| [ category.name, category.id ] }

    unless key.blank?
      family_categories.unshift [ "Add as new category", CREATE_NEW_KEY ]
    end

    family_categories
  end

  def requires_selection?
    false
  end

  def values_count
    import.rows.where(category: key).count
  end

  def mappable_class
    Category
  end

  def create_mappable!
    return unless creatable?

    parts = key.split(":", 2)

    if parts.length == 2
      parent_name = parts[0].strip
      child_name  = parts[1].strip

      # Ensure the parent category exists before creating the child.
      parent = import.family.categories.find_or_create_by!(name: parent_name) do |cat|
        cat.color = Category::COLORS.sample
        cat.lucide_icon = Category.suggested_icon(parent_name)
      end

      self.mappable = import.family.categories.find_or_create_by!(name: child_name) do |cat|
        cat.parent = parent
        cat.color = parent.color
        cat.lucide_icon = Category.suggested_icon(child_name)
      end
    else
      self.mappable = import.family.categories.find_or_create_by!(name: key) do |cat|
        cat.color = Category::COLORS.sample
        cat.lucide_icon = Category.suggested_icon(key)
      end
    end

    save!
  end
end
