# frozen_string_literal: true

# Assistant Conversations
class AssistantConversationsController < ApplicationController
  before_action :set_assistant_conversation, only: %i[show message source]

  def source
    citation = params[:citation]
    index_name = @assistant_conversation.raggable.index_name
    Chroma.connect_host = "http://localhost:8000"
    Chroma.logger = Logger.new($stdout)
    Chroma.log_level = Chroma::LEVEL_ERROR
    collection = Chroma::Resources::Collection.get(index_name)
    @document = collection.get(ids: [citation], where: nil, where_document: nil).first
    metadata = @document.metadata
    respondent_id = metadata["respondent_id"]
    @respondent = Respondent.find(respondent_id)
    @respondent_category = @respondent.respondent_category
    @project = @respondent_category.project
    render layout: nil
  end

  def create
    @project = Project.find(params[:project_id])
    a = AssistantConversation.create!(
      raggable_id: params[:raggable_id],
      raggable_type: params[:raggable_type],
      user: current_user
    )

    flash[:notice] = "New chat created!"
    if params[:raggable_type] == "RespondentCategory"
      @respondent_category = RespondentCategory.find(params[:raggable_id])
      redirect_to assistant_v2_project_respondent_category_path(@project, @respondent_category, conversation_id: a.id)
    else
      redirect_to assistant_v2_project_path(@project, conversation_id: a.id)
    end
  end

  def message
    begin
      question = params[:question]&.strip
      return head :bad_request if question.blank?

      # Chroma requires NO FILTERS if all are matching
      # If there are some filters then only create the filters

      # Builds out the filters
      filters = { respondent_ids: [], section: nil }

      if params[:tags]
        tags = params[:tags].map(&:to_i)
        respondent_filters = @assistant_conversation.raggable.respondents.joins(:tags)
                                                    .where(tags: { id: tags })
                                                    .group("respondents.id")
                                                    .having("COUNT(DISTINCT tags.id) = ?", tags.size).pluck(:id).map(&:to_s)
      elsif params[:respondent_ids]
        respondent_filters = if params[:respondent_ids]&.include?("all")
                               @assistant_conversation.raggable.respondents.pluck(:id).map(&:to_s)
                             else
                               params[:respondent_ids] || []
                             end
      end

      respondent_filters.reject!(&:blank?)

      filters[:respondent_ids] = respondent_filters

      section_filters = params[:section]
      filters[:section] = section_filters if section_filters.present?

      respondent_names = respondent_filters.any? ? Respondent.where(id: respondent_filters).pluck(:first_name).join(", ") : "All Respondents"
      section_name = section_filters.present? ? MasterSection.find_by(id: section_filters)&.name : "All Sections"

      # 'filters' holds the raw IDs (for Chroma/debugging)
      # 'context_names' holds the human-readable text (for the UI)
      metadata_hash = {
        filters: filters,
        context_names: {
          respondents: respondent_names,
          section: section_name
        }
      }

      Rails.logger.info("FILTERS IN CONTROLLER: #{filters}")

      @user_message = @assistant_conversation.assistant_messages.create!(
        role: "user",
        message: question,
        metadata: metadata_hash
      )
      @assistant_message = @assistant_conversation.assistant_messages.create!(
        role: "assistant",
        message: "",
        metadata: metadata_hash
      )

      RagAssistantAskJob.perform_later(@assistant_conversation.id, question, filters)
    rescue StandardError => e
      Rails.logger.error("Error in assistant ask job controller - #{e}")
    end

    respond_to do |format|
      format.turbo_stream
      format.html { redirect_back fallback_location: root_path }
    end
  end

  def show; end

  def destroy
    @project = Project.find(params[:project_id])
    @respondent_category = RespondentCategory.find(params[:respondent_category_id]) if params[:raggable_type] == "RespondentCategory"
    conversation = AssistantConversation.find(params[:id])
    conversation.destroy!

    flash[:notice] = "Conversation deleted!"
    if params[:raggable_type] == "RespondentCategory"
      redirect_to assistant_v2_project_respondent_category_path(@project, @respondent_category)
    else
      redirect_to assistant_v2_project_path(@project)
    end
  end

  private

  def set_assistant_conversation
    @assistant_conversation = AssistantConversation.find(params[:id])
  end
end
