app/models/ruby_conversations/message_prompt.rb



# frozen_string_literal: true

require 'active_model'
require_relative 'message_input'

module RubyConversations
  # Represents a prompt used to generate a message in a conversation
  class MessagePrompt
    include ActiveModel::Model

    # Define attributes
    attr_accessor :id, :message_id, :prompt_version_id, :name, :role, :content, :metadata,
                  :created_at, :updated_at, :message_inputs, :draft, :message, :llm

    # Define nested attributes writer
    def message_inputs_attributes=(attributes)
      @message_inputs ||= []
      attributes.each do |attrs|
        @message_inputs << RubyConversations::MessageInput.new(attrs)
      end
    end

    # Initialization
    def initialize(attributes = {})
      @message_inputs = [] # Initialize inputs array
      # Extract nested inputs before super
      inputs_attributes = extract_nested_attributes!(attributes, :message_inputs)

      super
      initialize_message_inputs(inputs_attributes)
    end

    # Handle nested inputs initialization
    def initialize_message_inputs(attributes_array)
      (attributes_array || []).each do |attrs|
        next if attrs.blank?

        @message_inputs << RubyConversations::MessageInput.new(attrs)
      end
    end

    # Attributes method for serialization/logging
    def attributes
      base_attributes.merge(message_inputs_attributes_hash)
    end

    # Method for API serialization
    def attributes_for_api
      {
        id: id,
        prompt_version_id: prompt_version_id,
        name: name,
        role: role,
        content: content,
        metadata: metadata,
        draft: draft,
        ai_message_inputs_attributes: message_inputs.map(&:attributes_for_api)
      }.compact
    end

    private

    def base_attributes
      identity_attributes.merge(content_attributes).merge(timestamp_attributes)
    end

    def identity_attributes
      {
        'id' => id,
        'message_id' => message_id,
        'prompt_version_id' => prompt_version_id,
        'message' => message
      }
    end

    def content_attributes
      {
        'name' => name,
        'role' => role,
        'content' => content,
        'metadata' => metadata,
        'draft' => draft
      }
    end

    def timestamp_attributes
      {
        'created_at' => created_at,
        'updated_at' => updated_at
      }
    end

    def message_inputs_attributes_hash
      {
        'message_inputs' => message_inputs.map(&:attributes)
      }
    end

    # Helper method to extract nested attributes
    def extract_nested_attributes!(attributes, key)
      nested = extract_key_attributes(attributes, key)
      nested_attributes = extract_key_attributes(attributes, "#{key}_attributes")
      nested.concat(nested_attributes)
    end

    def extract_key_attributes(attributes, key)
      attributes.delete(key) || attributes.delete(key.to_s) || attributes.delete(key.to_sym) || []
    end
  end
end