// src/tools/skills/search-skills.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved

import type { ToolDefinition } from "../../lib/ai-client.js";

import {
  DtpTool,
  type ToolArguments,
  type ToolContext,
} from "../../lib/tool.js";
import { AiSkill } from "../../models/ai-skill.js";
import { ChatSessionMode } from "../../models/chat-session.js";

export class SearchSkillsTool extends DtpTool {
  get name(): string {
    return "SearchSkillsTool";
  }
  get slug(): string {
    return "search-skills";
  }
  get metadata() {
    return {
      name: this.definition.function.name || "search_skills",
      category: "skills",
      tags: ["skill", "search", "find", "query"],
      modes: [
        ChatSessionMode.Plan,
        ChatSessionMode.Build,
        ChatSessionMode.Test,
        ChatSessionMode.Ship,
        ChatSessionMode.Develop,
      ],
    };
  }

  public definition: ToolDefinition = {
    type: "function",
    function: {
      name: "search_skills",
      description:
        "Search for skills using text search. Matches against skill names, descriptions, and tags. Returns a list of matching skills with their basic info. Use this to find relevant skills when you need guidance on a specific task, then fetch the skill(s) you need by ID to read their full content.",
      parameters: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description:
              "The search query. Use keywords that match skill names, descriptions, or tags.",
          },
        },
        required: ["query"],
      },
    },
  };

  public async execute(
    _context: ToolContext,
    args: ToolArguments,
  ): Promise<string> {
    const query = args.query as string | undefined;

    if (!query || query.trim().length === 0) {
      return this.error("INVALID_PARAMETER", "query is required.", {
        parameter: "query",
      });
    }

    try {
      const skills = await AiSkill.find(
        { $text: { $search: query } },
        { score: { $meta: "textScore" } },
      )
        .sort({ score: { $meta: "textScore" } })
        .limit(10)
        .lean();

      if (skills.length === 0) {
        return this.success(
          { skills: [], total: 0 },
          `No skills found matching "${query}".`,
        );
      }

      const results = skills.map((s) => ({
        skillId: s._id.toString(),
        name: s.name,
        description: s.description,
        tags: s.tags,
        modes: s.modes,
        isGlobal: s.user === null,
      }));
      return this.success(
        { results, total: results.length },
        `Found ${results.length} skill(s).`,
      );
    } catch (error) {
      const errorMessage =
        error instanceof Error ? error.message : String(error);
      return this.error(
        "OPERATION_FAILED",
        `Failed to search skills: ${errorMessage}`,
      );
    }
  }
}

export default new SearchSkillsTool();
