# frozen_string_literal: true

require "rails_helper"

RSpec.describe DiscourseAi::Automation::LlmToolTriage do
  fab!(:solver) { Fabricate(:user) }
  fab!(:new_user) { Fabricate(:user, trust_level: TrustLevel[0], created_at: 1.day.ago) }
  fab!(:topic) { Fabricate(:topic, user: new_user) }
  fab!(:post) { Fabricate(:post, topic: topic, user: new_user, raw: "How do I reset my password?") }
  fab!(:llm_model)
  fab!(:ai_persona) do
    persona = Fabricate(:ai_persona, default_llm: llm_model)
    persona.create_user
    persona
  end

  fab!(:tool) do
    tool_script = <<~JS
      function invoke(params) {
        const postId = context.post_id;
        const post = discourse.getPost(postId);
        const user = discourse.getUser(post.user_id);

        if (user.trust_level > 0) {
          return {
            processed: false,
            reason: "User is not new"
          };
        }

        const helper = discourse.getPersona("#{ai_persona.name}");
        const answer = helper.respondTo({ post_id: post.id });

        return {
          answer: answer,
          processed: true,
          reason: "answered question"
        };
      }
    JS

    AiTool.create!(
      name: "New User Question Answerer",
      tool_name: "new_user_question_answerer",
      description: "Automatically answers questions from new users when possible",
      parameters: [], # No parameters as required by llm_tool_triage
      script: tool_script,
      created_by_id: Discourse.system_user.id,
      summary: "Answers new user questions",
      enabled: true,
    )
  end

  before do
    SiteSetting.discourse_ai_enabled = true
    SiteSetting.ai_bot_enabled = true
  end

  it "It is able to answer new user questions" do
    result = nil
    DiscourseAi::Completions::Llm.with_prepared_responses(
      ["this is how you reset your password"],
    ) { result = described_class.handle(post: post, tool_id: tool.id) }
    expect(result["processed"]).to eq(true)
    response = post.topic.reload.posts.order(:post_number).last
    expect(response.raw).to eq("this is how you reset your password")
  end

  it "Is able to respond as a whisper if instructed" do
    # Create a tool with a script that explicitly requests a whisper response
    whisper_tool =
      AiTool.create!(
        name: "Whisper Triage Tool",
        tool_name: "whisper_triage_tool",
        description: "Responds with whispers to moderation issues",
        parameters: [],
        script: <<~JS,
      function invoke(params) {
        const postId = context.post_id;
        const post = discourse.getPost(postId);

        const helper = discourse.getPersona("#{ai_persona.name}");
        // Pass instructions to make response a whisper
        const answer = helper.respondTo({
          post_id: post.id,
          instructions: "Respond as a whisper for moderators only",
          whisper: true
        });

        return {
          answer: answer,
          processed: true,
          reason: "responded with whisper"
        };
      }
    JS
        created_by_id: Discourse.system_user.id,
        summary: "Responds with whispers",
        enabled: true,
      )

    result = nil
    DiscourseAi::Completions::Llm.with_prepared_responses(
      ["This moderation note is only visible to staff"],
    ) { result = described_class.handle(post: post, tool_id: whisper_tool.id) }

    expect(result["processed"]).to eq(true)
    response = post.topic.reload.posts.order(:post_number).last
    expect(response.raw).to eq("This moderation note is only visible to staff")
    # Check that the response is indeed a whisper
    expect(response.post_type).to eq(Post.types[:whisper])
  end
end
