module PageflowScrolled
  # @api private
  class ContentElement < Pageflow::ApplicationRecord
    POSITION_ORDER = [
      'pageflow_scrolled_storylines.position ASC',
      'pageflow_scrolled_chapters.position ASC',
      'pageflow_scrolled_sections.position ASC',
      'pageflow_scrolled_content_elements.position ASC'
    ].join(',')

    include Pageflow::SerializedConfiguration
    include Pageflow::AutoGeneratedPermaId
    include Pageflow::NestedRevisionComponent

    belongs_to :section

    def entry_for_auto_generated_perma_id
      section.chapter.storyline.revision.entry
    end

    def self.all_for_revision(revision)
      joins(section: {chapter: {storyline: :revision}})
        .where(pageflow_scrolled_storylines: {revision_id: revision})
        .order(POSITION_ORDER)
    end

    def self.select_used_type_names(revision, type_names)
      all_for_revision(revision)
        .where(type_name: type_names)
        .map(&:type_name)
        .uniq
    end

    # @api private
    class Batch
      def initialize(section, items)
        @section = section
        @storyline = section.chapter.storyline
        @items = items
      end

      def save!
        ContentElement.transaction do
          @items.map.with_index { |item, index|
            if item[:_delete]
              @section.content_elements.delete(item[:id])
              nil
            else
              create_or_update(item, index)
            end
          }.compact
        end
      end

      private

      def create_or_update(item, index)
        attributes = {
          section_id: @section.id,
          position: index
        }.merge(item.slice(:type_name, :configuration))

        if item[:id]
          @storyline.content_elements.update(item[:id], attributes)
        else
          @section.content_elements.create(attributes)
        end
      end
    end
  end
end
