# app/services/transcript_generator.rb
class TranscriptGenerator
  require "pandoc-ruby"

  def self.call(respondent)
    new(respondent).generate
  end

  def self.call_text(respondent)
    new(respondent).generate_text
  end

  def initialize(respondent)
    @respondent = respondent
    @sections = @respondent.transcript_sections.sort_by { |s| s["offset"] }
    # Initialize the Markdown document with the respondent's name as an H1
    @markdown_content = "# #{@respondent.name}\n\n"
  end

  def generate
    return nil unless @respondent.docx_transcript || @respondent.whisper_transcript

    if @respondent.docx_transcript.present?
      write_docx_style
    else
      write_whisper_style
    end

    PandocRuby.new(@markdown_content, from: :markdown).to_docx
  end

  def generate_text
    return nil unless @respondent.docx_transcript || @respondent.whisper_transcript

    if @respondent.docx_transcript.present?
      write_docx_style
    else
      write_whisper_style
    end

    @markdown_content
  end

  private

  def write_docx_style
    utterances = @respondent.docx_transcript.verbose_json
    process_utterances(utterances) do |utterance|
      utterance["text"].gsub("\n", " ").strip
    end
  end

  def write_whisper_style
    utterances = @respondent.whisper_transcript.verbose_json
    speaker_map = @respondent.displayed_speaker_labels

    process_utterances(utterances) do |utterance|
      speaker = speaker_map[utterance["speaker"]] || utterance["speaker"]
      text = "#{speaker}: #{utterance['text']}"
      @respondent.sanitize_for_docx(text)
    end
  end

  def process_utterances(utterances)
    if @sections.empty?
      utterances.each do |u|
        text = yield(u)
        @markdown_content += "#{text}\n\n" if text.present?
      end
    else
      # Handle Ungrouped (before first section)
      first_offset = @sections[0]["offset"]
      if first_offset.positive?
        utterances[0...first_offset].each do |u|
          text = yield(u)
          @markdown_content += "#{text}\n\n" if text.present?
        end
      end

      # Handle Sections
      @sections.each_with_index do |section, idx|
        @markdown_content += "## #{section['name']}\n\n"

        start_idx = section["offset"]
        end_idx = @sections[idx + 1] ? @sections[idx + 1]["offset"] : utterances.length

        utterances[start_idx...end_idx].each do |u|
          text = yield(u)
          @markdown_content += "#{text}\n\n" if text.present?
        end
      end
    end
  end
end
