/**
 * Skill Tools
 *
 * Tools for invoking and listing skills during task execution.
 * Skills provide specialized instructions for repeatable tasks.
 */

import { z } from 'zod';
import { defineTool, type ToolResult } from './types.js';
import { SkillRegistry } from '../../skills/registry.js';
import type { Skill, SkillInvocation } from '../../skills/types.js';

/**
 * Skill Tool
 *
 * Invoke a skill for specialized task execution.
 */
export const skillTool = defineTool({
  name: 'skill',
  description: `Invoke a skill for specialized task execution.

Skills provide focused instructions for common tasks like:
- commit: Generate commit messages following conventions
- review-pr: Review PRs with code standards
- security-review: Security-focused code review

When you invoke a skill, you receive its instructions which you should follow.
Use list_skills to see available skills.`,
  category: 'planning',
  schema: z.object({
    skill: z.string().min(1).describe('Name of the skill to invoke'),
    args: z.string().optional().describe('Optional arguments for the skill (e.g., PR number, file path)'),
  }),
  async execute(input): Promise<ToolResult<{
    skill_name: string;
    description: string;
    instructions: string;
    tools: string[];
    scripts: string[];
    args: string;
    message: string;
  }>> {
    const { skill: skillName, args = '' } = input;
    const registry = SkillRegistry.getInstance();

    const skillObj = await registry.getSkill(skillName);

    if (!skillObj) {
      const available = await registry.listSkills();
      if (available.length > 0) {
        return {
          success: false,
          error: `Skill '${skillName}' not found`,
          suggestions: [`Available skills: ${available.join(', ')}`],
        };
      } else {
        return {
          success: false,
          error: `Skill '${skillName}' not found. No skills are currently loaded.`,
          suggestions: [
            'Create skills in .emdash/skills/<skill-name>/SKILL.md',
            'Skills are loaded from the .emdash/skills/ directory',
          ],
        };
      }
    }

    // Build the skill activation response
    const responseParts: string[] = [
      `# Skill Activated: ${skillObj.name}`,
      '',
      `**Description**: ${skillObj.description}`,
      '',
    ];

    if (args) {
      responseParts.push(`**Arguments**: ${args}`, '');
    }

    if (skillObj.tools.length > 0) {
      responseParts.push(`**Required tools**: ${skillObj.tools.join(', ')}`, '');
    }

    // Include available scripts
    if (skillObj.scripts.length > 0) {
      responseParts.push('**Available Scripts**:', '');
      for (const scriptPath of skillObj.scripts) {
        const scriptName = scriptPath.split('/').pop() ?? scriptPath;
        responseParts.push(
          `- \`${scriptPath}\` - Run with: \`bash ${scriptPath}\` or \`./${scriptName}\` from skill directory`
        );
      }
      responseParts.push(
        '',
        '*Scripts are self-contained executables. Run them using Bash tool when needed.*',
        ''
      );
    }

    responseParts.push('---', '', skillObj.instructions);

    return {
      success: true,
      data: {
        skill_name: skillObj.name,
        description: skillObj.description,
        instructions: skillObj.instructions,
        tools: skillObj.tools,
        scripts: skillObj.scripts,
        args,
        message: responseParts.join('\n'),
      },
    };
  },
});

/**
 * List Skills Tool
 *
 * List all available skills and their descriptions.
 */
export const listSkillsTool = defineTool({
  name: 'list_skills',
  description: 'List all available skills and their descriptions.',
  category: 'planning',
  schema: z.object({}),
  async execute(): Promise<ToolResult<{
    skills: Array<{
      name: string;
      description: string;
      userInvocable: boolean;
      tools: string[];
      scripts: string[];
    }>;
    count: number;
    message: string;
  }>> {
    const registry = SkillRegistry.getInstance();
    const skills = await registry.getAllSkills();

    if (skills.size === 0) {
      return {
        success: true,
        data: {
          skills: [],
          count: 0,
          message: 'No skills loaded. Create skills in .emdash/skills/<skill-name>/SKILL.md',
        },
      };
    }

    const skillsList: Array<{
      name: string;
      description: string;
      userInvocable: boolean;
      tools: string[];
      scripts: string[];
    }> = [];

    for (const skill of skills.values()) {
      skillsList.push({
        name: skill.name,
        description: skill.description,
        userInvocable: skill.userInvocable,
        tools: skill.tools,
        scripts: skill.scripts,
      });
    }

    // Build human-readable message
    const lines: string[] = ['# Available Skills', ''];
    for (const s of skillsList) {
      const invocable = s.userInvocable ? ` (invoke with /${s.name})` : '';
      const scriptsNote = s.scripts.length > 0 ? ` [has ${s.scripts.length} script(s)]` : '';
      lines.push(`- **${s.name}**: ${s.description}${invocable}${scriptsNote}`);
    }

    return {
      success: true,
      data: {
        skills: skillsList,
        count: skillsList.length,
        message: lines.join('\n'),
      },
    };
  },
});

/**
 * All skill tools
 */
export const skillTools = [skillTool, listSkillsTool];
