class Generators::Avo::EjectGenerator

def add_scope?(component)

def add_scope?(component)
  component.starts_with?("avo/views/") && options[:scope].present?
end

def confirm_ejection_on(path)

def confirm_ejection_on(path)
  say("By ejecting the '#{path}' \033[1myou'll take on the responsibility for maintain it.", :yellow)
  yes?("Are you sure you want to eject the '#{path}'? [y/N]", :yellow)
end

def eject(path, dest_path = nil)

def eject(path, dest_path = nil)
  copy_file ::Avo::Engine.root.join(path), ::Rails.root.join(dest_path || path)
end

def eject_component

def eject_component
  # Underscore the component name
  # Example: Avo::Views::ResourceIndexComponent => avo/views/resource_index_component
  component = options[:component].underscore
  # Get the component path for both, the rb and erb files
  rb, erb = ["app/components/#{component}.rb", "app/components/#{component}.html.erb"]
  # Return if one of the components doesn't exist
  if !path_exists?(rb) || !path_exists?(erb)
    return say("Failed to find the `#{options[:component]}` component.", :yellow)
  end
  # Add the scope to the component if it's possible
  if add_scope? component
    component = component.gsub("avo/views/", "avo/views/#{options[:scope]}/")
    added_scope = true
  end
  # Confirm the ejection
  return unless confirm_ejection_on component.camelize
  # Get the destination path for both, the rb and erb files
  dest_rb = "#{::Avo.configuration.view_component_path}/#{component}.rb"
  dest_erb = "#{::Avo.configuration.view_component_path}/#{component}.html.erb"
  # Eject the component
  eject rb, dest_rb
  eject erb, dest_erb
  # Remame the component class if scope was added
  # Example: Avo::Views::ResourceIndexComponent => Avo::Views::Admins::ResourceIndexComponent
  if added_scope
    [dest_rb, dest_erb].each do |path|
      modified_content = File.read(path).gsub("Avo::Views::", "Avo::Views::#{options[:scope].camelize}::")
      File.open(path, "w") do |file|
        file.puts modified_content
      end
    end
    say "You can now use this component on any resource by configuring the 'self.components' option.\n" \
        "  self.components = {\n" \
        "    #{component.split("/").last}: #{component.camelize}\n" \
        "  }", :green
  end
end

def eject_partial

def eject_partial
  if options[:partial].starts_with?(":")
    template_id = path_to_sym options[:partial]
    template_path = TEMPLATES[template_id]
    if path_exists? template_path
      return unless confirm_ejection_on template_path
      eject template_path
    else
      say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
    end
  elsif path_exists? options[:partial]
    return unless confirm_ejection_on template_path
    eject options[:partial]
  else
    say("Failed to find the `#{options[:partial]}` template.", :yellow)
  end
end

def handle

def handle
  if options[:partial].present?
    eject_partial
  elsif options[:component].present?
    eject_component
  else
    say "Please specify a partial or a component to eject.\n" \
        "Examples: rails g avo:eject --partial :logo\n" \
        "          rails g avo:eject --partial app/views/layouts/avo/application.html.erb\n" \
        "          rails g avo:eject --component Avo::Index::TableRowComponent\n" \
        "          rails g avo:eject --component avo/index/table_row_component\n" \
        "          rails g avo:eject --component Avo::Views::ResourceIndexComponent --scope users\n" \
        "          rails g avo:eject --component avo/views/resource_index_component --scope users", :yellow
  end
end

def path_exists?(path)

def path_exists?(path)
  path.present? && File.file?(::Avo::Engine.root.join(path))
end

def path_to_sym(filename)

def path_to_sym(filename)
  template_id = filename.dup
  template_id[0] = ""
  template_id.to_sym
end