class Chunk < ApplicationRecord
  CHUNK_SIZE_CHARS = 2000
  CHUNK_OVERLAP_CHARS = 200
  belongs_to :chunkable, polymorphic: true
  has_neighbors :embedding
  before_save :generate_embedding, if: :content_changed?

  def self.generate_for(respondent)
    ActiveRecord::Base.transaction do
      Chunk.where(chunkable: respondent).destroy_all
      Chunk.where(chunkable: respondent.transcript_sections).destroy_all

      sections = respondent.transcript_sections.joins(:master_section).order("master_sections.position")

      if sections.exists?
        sections.each do |section|
          text = section.content || ""
          text_chunks = _split_text(text)

          text_chunks.each_with_index do |text_chunk, index|
            Chunk.create!(
              chunkable: section,
              content: text_chunk,
              chunk_index: index
            )
          end
        end

      else
        # Case 1: No sections. Chunk the entire respondent's full_text.
        text = respondent.full_text || ""
        text_chunks = _split_text(text)

        text_chunks.each_with_index do |text_chunk, index|
          Chunk.create!(
            chunkable: respondent,
            content: text_chunk,
            chunk_index: index
          )
        end
      end
    end
  end

  def citation
    "Source: Chunk #{id}"
  end

  def self._split_text(text)
    return [] if text.blank?

    chunks = []
    start_index = 0

    while start_index < text.length
      end_index = [start_index + CHUNK_SIZE_CHARS, text.length].min
      chunks << text[start_index...end_index]

      break if end_index == text.length

      start_index += (CHUNK_SIZE_CHARS - CHUNK_OVERLAP_CHARS)
    end

    chunks
  end

  private

  def generate_embedding
    model_map = FeatureModelMap.for_feature!("TRANSCRIPT_EMBEDDINGS")
    response = RubyLLM.embed(content, model: model_map.llm_model_name, provider: model_map.provider)
    self.embedding = response.vectors
  rescue StandardError => e
    Rails.logger.error "Failed to generate embedding for Chunk #{id}: #{e.message}"
  end
end
