module RubyLLM::Providers::Bedrock::Chat

def add_optional_fields(payload, system_content:, tools:)

def add_optional_fields(payload, system_content:, tools:)
  payload[:tools] = tools.values.map { |t| function_for(t) } if tools.any?
  payload[:system] = system_content unless system_content.empty?
end

def build_base_payload(chat_messages, temperature, model)

def build_base_payload(chat_messages, temperature, model)
  {
    anthropic_version: 'bedrock-2023-05-31',
    messages: chat_messages.map { |msg| format_message(msg) },
    temperature: temperature,
    max_tokens: RubyLLM.models.find(model).max_tokens
  }
end

def build_message(data, content, tool_use)

def build_message(data, content, tool_use)
  Message.new(
    role: :assistant,
    content: content,
    tool_calls: parse_tool_calls(tool_use),
    input_tokens: data.dig('usage', 'input_tokens'),
    output_tokens: data.dig('usage', 'output_tokens'),
    model_id: data['model']
  )
end

def build_system_content(system_messages)

def build_system_content(system_messages)
  if system_messages.length > 1
    RubyLLM.logger.warn(
      "Amazon Bedrock's Claude implementation only supports a single system message. " \
      'Multiple system messages will be combined into one.'
    )
  end
  system_messages.map { |msg| format_message(msg)[:content] }.join("\n\n")
end

def completion_url

def completion_url
  "model/#{@model_id}/invoke"
end

def convert_role(role)

def convert_role(role)
  case role
  when :tool, :user then 'user'
  when :system then 'system'
  else 'assistant'
  end
end

def extract_text_content(blocks)

def extract_text_content(blocks)
  text_blocks = blocks.select { |c| c['type'] == 'text' }
  text_blocks.map { |c| c['text'] }.join
end

def format_basic_message(msg)

def format_basic_message(msg)
  {
    role: convert_role(msg.role),
    content: Anthropic::Media.format_content(msg.content)
  }
end

def format_message(msg)

def format_message(msg)
  if msg.tool_call?
    format_tool_call(msg)
  elsif msg.tool_result?
    format_tool_result(msg)
  else
    format_basic_message(msg)
  end
end

def parse_completion_response(response)

def parse_completion_response(response)
  data = response.body
  content_blocks = data['content'] || []
  text_content = extract_text_content(content_blocks)
  tool_use = find_tool_use(content_blocks)
  build_message(data, text_content, tool_use)
end

def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument

rubocop:disable Lint/UnusedMethodArgument
def render_payload(messages, tools:, temperature:, model:, stream: false) # rubocop:disable Lint/UnusedMethodArgument
  # Hold model_id in instance variable for use in completion_url and stream_url
  @model_id = model
  system_messages, chat_messages = separate_messages(messages)
  system_content = build_system_content(system_messages)
  build_base_payload(chat_messages, temperature, model).tap do |payload|
    add_optional_fields(payload, system_content:, tools:)
  end
end

def separate_messages(messages)

def separate_messages(messages)
  messages.partition { |msg| msg.role == :system }
end