#!/usr/bin/env node
// ChatOps: runs a skill from a GitHub issue/PR comment and replies inline.
// Triggered by .github/workflows/skill-bot.yml on comments like:
//   /skill rice-prioritisation
//   here is my backlog: ...
// or:  /skill list
//
// Env (provided by the workflow): COMMENT_BODY, ISSUE_NUMBER, GITHUB_REPOSITORY,
// GITHUB_TOKEN, ANTHROPIC_API_KEY.
import { readFileSync, readdirSync, existsSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { complete, parseSkill } from '../bin/lib/anthropic.mjs';

const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const REPO = process.env.GITHUB_REPOSITORY;
const ISSUE = process.env.ISSUE_NUMBER;
const GH_TOKEN = process.env.GITHUB_TOKEN;
const API_KEY = process.env.ANTHROPIC_API_KEY;
const BODY = process.env.COMMENT_BODY || '';

async function postComment(markdown) {
  const res = await fetch(`https://api.github.com/repos/${REPO}/issues/${ISSUE}/comments`, {
    method: 'POST',
    headers: { authorization: `Bearer ${GH_TOKEN}`, accept: 'application/vnd.github+json', 'content-type': 'application/json' },
    body: JSON.stringify({ body: markdown }),
  });
  if (!res.ok) { console.error('Failed to post comment:', res.status, await res.text()); process.exit(1); }
}

const FOOTER = `\n\n---\n<sub>🤖 Generated by a [PM Skills](https://github.com/${REPO}) skill. Comment \`/skill <name>\` followed by your input to run another. · [Browse all 174 →](https://mohitagw15856.github.io/pm-claude-skills/)</sub>`;

function listSkills() {
  return readdirSync(join(root, 'skills'))
    .filter((n) => existsSync(join(root, 'skills', n, 'SKILL.md')))
    .sort();
}

async function main() {
  // Strip the "/skill" trigger; first token is the skill name (or "list"), rest is input.
  const rest = BODY.replace(/^\s*\/skill\b/i, '').trim();
  const m = rest.match(/^([a-z0-9-]+)([\s\S]*)$/i);

  if (!m || m[1].toLowerCase() === 'list' || m[1].toLowerCase() === 'help') {
    const names = listSkills();
    const sample = ['prd-template', 'rice-prioritisation', 'executive-update', 'competitor-teardown', 'meeting-notes'].filter((n) => names.includes(n));
    await postComment(
      `**PM Skills bot** — run any of ${names.length} skills right here.\n\n` +
      `**Usage:** comment \`/skill <name>\` and put your input on the lines below.\n\n` +
      `**Popular:** ${sample.map((n) => `\`${n}\``).join(' · ')}\n\n` +
      `Full list: https://mohitagw15856.github.io/pm-claude-skills/catalog.html` + FOOTER
    );
    return;
  }

  const name = m[1];
  const input = m[2].trim();
  const skillFile = join(root, 'skills', name, 'SKILL.md');

  if (!existsSync(skillFile)) {
    const all = listSkills();
    const near = all.filter((n) => n.includes(name.split('-')[0]) || name.includes(n.split('-')[0])).slice(0, 5);
    await postComment(
      `❓ No skill named \`${name}\`.` +
      (near.length ? ` Did you mean: ${near.map((n) => `\`${n}\``).join(' · ')}?` : '') +
      `\n\nTry \`/skill list\` or browse the [catalog](https://mohitagw15856.github.io/pm-claude-skills/catalog.html).` + FOOTER
    );
    return;
  }

  if (!input) {
    await postComment(`The \`${name}\` skill needs input. Comment \`/skill ${name}\` and add your context on the next lines.` + FOOTER);
    return;
  }

  const { body } = parseSkill(readFileSync(skillFile, 'utf8'));
  const system = body + '\n\n---\nExecute this skill now on the input below and produce the complete output. Do not ask follow-up questions — work with what is given and note any assumptions.';
  let output;
  try {
    output = await complete({ apiKey: API_KEY, model: 'claude-sonnet-4-6', system, messages: [{ role: 'user', content: input }], maxTokens: 4096 });
  } catch (e) {
    await postComment(`⚠️ The \`${name}\` skill failed to run: ${e.message}` + FOOTER);
    process.exit(1);
  }
  await postComment(`### 🛠️ ${name}\n\n${output.trim()}${FOOTER}`);
}

main().catch((e) => { console.error(e); process.exit(1); });
