# frozen_string_literal: true

# Transcript Sections
class MasterSectionsController < ApplicationController
  before_action :set_master_section, only: %i[show edit update destroy]

  def import_with_dg
    require "pandoc-ruby"

    file = params[:file]
    project_id = params[:project_id].to_i
    respondent_category_id = params[:respondent_category_id].to_i

    if file.blank?
      redirect_back fallback_location: root_path, alert: "Please upload a .docx file."
      return
    end

    valid_mime_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    unless file.content_type == valid_mime_type || file.original_filename.end_with?(".docx")
      redirect_back fallback_location: root_path, alert: "Only .docx files are allowed."
      return
    end

    begin
      extracted_text = PandocRuby.new([file.tempfile.path], from: :docx).to_plain

      GenerateSectionsWithDgJob.perform_later(
        metadata: { dg_text: extracted_text, project_id:, respondent_category_id: },
        user_id: current_user.id
      )

      redirect_back fallback_location: root_path, notice: "Discussion Guide uploaded successfully. Generating sections..."
    rescue StandardError => e
      Rails.logger.error("Failed to parse docx file with Pandoc: #{e.message}")
      redirect_back fallback_location: root_path, alert: "There was an error reading the document."
    end
  end

  def import
    require "csv"

    file = params[:file]
    project_id = params[:project_id]
    respondent_category_id = params[:respondent_category_id]

    if file.blank?
      redirect_back fallback_location: root_path, alert: "Please upload a CSV file."
      return
    end

    # Basic validation to ensure it's a CSV
    unless file.content_type == "text/csv" || file.original_filename.end_with?(".csv")
      redirect_back fallback_location: root_path, alert: "Only CSV files are allowed."
      return
    end

    imported_count = 0

    begin
      # Read the CSV file
      CSV.foreach(file.path, headers: false) do |row|
        raw_name = row[0].to_s.strip

        # Skip empty rows or generic header labels
        next if raw_name.blank? || raw_name.downcase.in?(["name", "section", "section name", "header"])

        # Sanitize the string: remove `, ', ", \
        sanitized_name = raw_name.gsub(/[`'"\\]/, "").strip

        # Skip if the sanitization left the string empty
        next if sanitized_name.blank?

        MasterSection.create!(
          name: sanitized_name,
          project_id:,
          respondent_category_id:
        )
        imported_count += 1
      end

      RespondentCategory.find(respondent_category_id).update!(requires_section_regeneration: true)
      redirect_back fallback_location: root_path, notice: "Successfully imported #{imported_count} sections."
    rescue CSV::MalformedCSVError
      redirect_back fallback_location: root_path, alert: "The file could not be parsed. Please ensure it is a valid CSV."
    rescue StandardError => e
      redirect_back fallback_location: root_path, alert: "Error importing file: #{e.message}"
    end
  end

  def create_section
    master_section = MasterSection.new(name: params["sectionName"], project_id: params["projectId"],
                                       respondent_category_id: params["respondentCategoryId"])
    if master_section.save!
      RespondentCategory.find(params["respondentCategoryId"]).update!(requires_section_regeneration: true)
      render json: { status: "ok", new_section: master_section }
    else
      render json: { status: "error" }
    end
  end

  def delete_section
    MasterSection.destroy(params["id"])
    TranscriptSection.delete_sections_with_master_id(params["id"])
    RespondentCategory.find(params["respondentCategoryId"]).update!(requires_section_regeneration: true)
    render json: { status: "ok" }
  end

  def edit_section
    master_section = MasterSection.find(params["sectionId"])
    if master_section.nil?
      render json: { status: "error" }
    else
      master_section.update!(name: params["sectionName"])
      TranscriptSection.update_section_name(master_section.id, master_section.name)
      render json: { status: "ok" }
    end
  end

  def reorder
    movement = params[:movement]
    respondent_category = RespondentCategory.find(params[:respondent_category_id])
    return render json: { status: "error" } if respondent_category.nil?

    master_section = respondent_category.master_sections.find(params[:id])
    return render json: { status: "error" } if master_section.nil?

    if movement == "up"
      master_section.move_higher
    else
      master_section.move_lower
    end
    render json: { status: "ok", updated_sections: respondent_category.master_sections.order(:position) }
  end

  def update_order
    respondent_category = RespondentCategory.find(params[:respondent_category_id])
    return render json: { status: "error" } if respondent_category.nil?

    master_section = respondent_category.master_sections.find(params[:id])
    return render json: { status: "error" } if master_section.nil?

    # Get new position from params
    new_position = params[:new_position].to_i

    # Update the position
    master_section.insert_at(new_position)

    # Return updated sections
    render json: {
      status: "ok",
      updated_sections: respondent_category.master_sections.order(:position)
    }
  end

  def get_sections # rubocop:disable Naming/AccessorMethodName
    respondent_category = RespondentCategory.find(params[:respondent_category_id])
    return render json: { status: "error" } if respondent_category.nil?

    render json: {
      status: "ok",
      sections: respondent_category.master_sections.order(:position)
    }
  end

  # GET /master_sections or /master_sections.json
  def index
    @master_sections = MasterSection.all
  end

  # GET /master_sections/1 or /master_sections/1.json
  def show; end

  # GET /master_sections/new
  def new
    @project = Project.find(params[:project_id]) if params[:project_id]
    @master_section = MasterSection.new
  end

  # GET /master_sections/1/edit
  def edit
    @project = @master_section.project
  end

  # POST /master_sections or /master_sections.json
  def create
    @master_section = MasterSection.new(master_section_params)

    respond_to do |format|
      if @master_section.save
        format.html do
          redirect_to (@master_section.project.nil? ? master_sections_url : master_sections_project_path(@master_section.project)),
                      notice: "Master section was successfully created."
        end
        format.json { render :show, status: :created, location: @master_section }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @master_section.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /master_sections/1 or /master_sections/1.json
  def update
    respond_to do |format|
      if @master_section.update(master_section_params)
        format.html do
          redirect_to (@master_section.project.nil? ? master_sections_url : master_sections_project_path(@master_section.project)),
                      notice: "Master section was successfully updated."
        end
        format.json { render :show, status: :ok, location: @master_section }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @master_section.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /master_sections/1 or /master_sections/1.json
  def destroy
    @master_section.destroy

    respond_to do |format|
      format.html do
        redirect_to (@master_section.project.nil? ? master_sections_url : master_sections_project_path(@master_section.project)),
                    notice: "Master section was successfully destroyed."
      end
      format.json { head :no_content }
    end
  end

  def self.reset_category_report_status(respondent_category_id)
    RespondentCategory.find(respondent_category_id).update!(requires_section_regeneration: true)
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_master_section
    @master_section = MasterSection.find(params[:id])
  end

  # Only allow a list of trusted parameters through.
  def master_section_params
    params.require(:master_section).permit(:name, :project_id)
  end
end
