class TranscriptSectionsController < ApplicationController
  before_action :set_ancestors
  after_action :reset_assistant, only: %i[create destroy]

  def reset_assistant
    @respondent_category.update!(index_name: nil)
    @project.update!(index_name: nil)
    AssistantConversation.where(raggable: @respondent_category).update!(outdated: true)
    AssistantConversation.where(raggable: @project).update!(outdated: true)
  end

  def create
    @section = @respondent.transcript_sections.new(section_params)

    # 1. Fetch the source transcript JSON (Whisper or Docx)
    # We need the full list of sentences to slice the content strings
    transcript_data = fetch_transcript_json

    # 2. Determine the range for the NEW section
    # We look for the closest existing section that starts AFTER our new offset
    next_section = @respondent.transcript_sections
                              .where('"offset" > ?', @section.offset)
                              .order(:offset).first

    start_index = @section.offset.to_i
    # If there is a next section, stop before it. Otherwise, go to the end.
    end_index = next_section ? next_section.offset - 1 : transcript_data.length - 1

    # 3. Generate Content for the NEW section
    @section.content = generate_content_string(transcript_data, start_index, end_index)

    if @section.save
      # 4. Update the PREVIOUS section (Important!)
      # The section immediately before this one now has to stop where this one begins.
      update_previous_section_content(transcript_data, @section.offset)
      @respondent_category.update!(requires_section_regeneration: true)
      render json: @section, status: :created
    else
      render json: { errors: @section.errors.full_messages }, status: :unprocessable_entity
    end
  end

  def destroy
    @section = @respondent.transcript_sections.find(params[:id])
    deleted_offset = @section.offset

    # 1. Capture the transcript data before we lose the section reference
    transcript_data = fetch_transcript_json

    if @section.destroy
      # 2. Find the section that immediately precedes the one we just deleted
      # Use double quotes for "offset" because it is a Postgres reserved word
      prev_section = @respondent.transcript_sections
                                .where('"offset" < ?', deleted_offset)
                                .order(offset: :desc).first

      if prev_section
        # 3. Find the NEW "next" section (the one after the gap we just created)
        next_section = @respondent.transcript_sections
                                  .where('"offset" > ?', deleted_offset)
                                  .order(offset: :asc).first

        # 4. Calculate the new end boundary for the previous section
        # If there is a next section, stop right before it. Otherwise, go to the end.
        new_end_index = next_section ? (next_section.offset - 1) : (transcript_data.length - 1)

        # 5. Regenerate the content string
        new_content = generate_content_string(transcript_data, prev_section.offset, new_end_index)

        # 6. Save the update
        prev_section.update!(content: new_content)
      end

      @respondent_category.update!(requires_section_regeneration: true)
      head :no_content
    else
      render json: { errors: "Could not delete section" }, status: :unprocessable_entity
    end
  end

  private

  def set_ancestors
    @project = Project.find(params[:project_id])
    @respondent_category = RespondentCategory.find(params[:respondent_category_id])
    @respondent = Respondent.find(params[:respondent_id])
  end

  def section_params
    params.require(:transcript_section).permit(:name, :offset, :master_section_id)
  end

  # Helper to get the raw array of utterances based on transcript type
  def fetch_transcript_json
    if @respondent.whisper_transcript.present?
      @respondent.whisper_transcript.verbose_json
    elsif @respondent.docx_transcript.present?
      # Use verbose_json (or verbose_json_indexed depending on your specific structure)
      # defaulting to verbose_json based on your update_docx_transcript snippet
      @respondent.docx_transcript.verbose_json
    else
      []
    end
  end

  # Helper to slice JSON and join speaker + text
  def generate_content_string(data, start_idx, end_idx)
    return "" if start_idx > end_idx || data.empty?

    # Ensure indices are within bounds
    start_idx = [0, start_idx].max
    end_idx = [end_idx, data.length - 1].min

    subset = data[start_idx..end_idx]
    subset.collect do |x|
      "#{x['speaker']}: #{x['text']}"
    end.join("\n\n")
  end

  # Logic to truncate the previous section when a new one is inserted
  def update_previous_section_content(data, new_section_offset)
    prev_section = @respondent.transcript_sections
                              .where('"offset" < ?', new_section_offset)
                              .order(:offset).last

    return unless prev_section

    # The previous section now ends exactly one index before the new section starts
    new_prev_end_index = new_section_offset.to_i - 1
    new_content = generate_content_string(data, prev_section.offset, new_prev_end_index)
    prev_section.update(content: new_content)
  end
end
