class CloneRespondentCategoryJob < ApplicationJob
  queue_as :default

  def perform(respondent_category_id)
    original_category = RespondentCategory.find_by(id: respondent_category_id)
    return unless original_category

    # Wrap the entire clone process in a transaction
    ActiveRecord::Base.transaction do
      # 1. Clone the Respondent Category
      new_category = original_category.dup
      new_category.name = "Copy of #{original_category.name}"

      # Reset assistant and report generation states
      new_category.assistant_id = nil
      new_category.index_name = nil
      new_category.requires_section_regeneration = false
      new_category.requires_insight_regeneration = false
      new_category.all_data_section_report_generated = false
      new_category.all_data_insight_report_generated = false

      new_category.save!

      # 2. Clone Master Sections
      original_category.master_sections.find_each do |master_section|
        new_master_section = master_section.dup

        # Link to the new category; name, project_id, and position remain the same
        new_master_section.respondent_category_id = new_category.id

        new_master_section.save!
      end

      # Cache the newly created master sections by name for O(1) lookup
      # Structure: { "Section Name" => NewMasterSectionRecord }
      new_ms_cache = new_category.master_sections.index_by(&:name)

      # 3. Clone associated Respondents
      original_category.respondents.find_each do |respondent|
        new_respondent = respondent.dup

        # Reassign to the newly created category
        new_respondent.respondent_category_id = new_category.id

        # Copy file attachments
        new_respondent.audio_file = respondent.audio_file if respondent.audio_file.present?
        new_respondent.video_file = respondent.video_file if respondent.video_file.present?
        new_respondent.transcript = respondent.transcript if respondent.transcript.present?

        # Update specific respondent attributes
        new_respondent.first_name = "Copy of #{respondent.first_name}"
        new_respondent.summary = nil

        # Preserve Tag Associations
        # This automatically creates the respondent_tags join records
        # for the new_respondent, linking it to the same tags as the original.
        new_respondent.tag_ids = respondent.tag_ids

        new_respondent.save!

        # 4. Clone associated Transcript Sections
        respondent.transcript_sections.find_each do |section|
          new_section = section.dup
          new_section.respondent_id = new_respondent.id

          # Assign the new master_section_id using our cache
          new_section.master_section_id = new_ms_cache[section.name].id if section.name.present? && new_ms_cache[section.name]

          new_section.save!
        end

        # 3. Clone associated Transcripts (Docx or Whisper)
        if respondent.respond_to?(:docx_transcript) && respondent.docx_transcript.present?
          new_docx = respondent.docx_transcript.dup
          new_docx.respondent_id = new_respondent.id
          new_docx.save!
        elsif respondent.respond_to?(:whisper_transcript) && respondent.whisper_transcript.present?
          new_whisper = respondent.whisper_transcript.dup
          new_whisper.respondent_id = new_respondent.id
          new_whisper.save!
        end
      end
    end
  rescue StandardError => e
    # Log the error if the transaction fails and rolls back
    Rails.logger.error("Failed to clone RespondentCategory ##{respondent_category_id}: #{e.message}")
    # raise e # Re-raise to let Sidekiq handle retries
  end
end
