import { readdir, readFile, writeFile } from 'fs/promises';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { pathToFileURL } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const SKILLS_DIR = __dirname;

export const name = 'self-improve';
export const description = 'Create new skills or improve existing ones based on identified gaps';

export async function execute(ctx) {
  // Read existing skills to understand what we already have
  const files = await readdir(SKILLS_DIR);
  const skillFiles = files.filter(f => f.endsWith('.mjs') && f !== 'self-improve.mjs');

  let skillDescriptions = '';
  for (const file of skillFiles) {
    try {
      const content = await readFile(join(SKILLS_DIR, file), 'utf-8');
      const nameMatch = content.match(/export const name = ['"]([^'"]+)['"]/);
      const descMatch = content.match(/export const description = ['"]([^'"]+)['"]/);
      skillDescriptions += `- ${nameMatch?.[1] || file}: ${descMatch?.[1] || 'no description'}\n`;
    } catch {}
  }

  // Get recent events for context
  const { getEvents } = await import('../db.mjs');
  const recentEvents = getEvents({ limit: 20 });
  const eventLog = recentEvents.reverse().map(e =>
    `[${e.type}] ${e.content.slice(0, 100)}`
  ).join('\n');

  const prompt = `You are an autonomous AI agent that can improve itself by writing new skills.

Current skills:
${skillDescriptions}

Recent activity:
${eventLog || '(none yet)'}

Based on what skills exist and recent activity, design ONE new useful skill that would make you more capable. The skill should be genuinely useful, not redundant with existing skills.

Write a complete Node.js ESM module for the skill. It must export:
- name (string)
- description (string)
- execute(ctx) — async function

The ctx object provides:
- ctx.askLLM(prompt, { model }) — call the LLM
- ctx.pickModel(taskType) — get appropriate model name
- ctx.remember(key, content, category) — store a memory
- ctx.recall(key) — retrieve a memory
- ctx.recallAll(category?) — get all memories
- ctx.addEvent(type, source, content, metadata?) — log an event
- ctx.writeOutputFile(filename, content) — write to output/
- ctx.args — optional arguments object

Respond with ONLY the JavaScript module code. No explanation, no markdown fences. Start with import statements or export const.`;

  const code = await ctx.askLLM(prompt, { model: ctx.pickModel('self-improve') });

  // Validate the generated code before writing
  const forbidden = ['child_process', 'execSync', 'spawnSync', 'rmSync', 'unlinkSync', 'process.exit', 'require('];
  for (const pattern of forbidden) {
    if (code.includes(pattern)) {
      ctx.addEvent('error', 'system', `Self-improve blocked: generated code contains forbidden pattern "${pattern}"`);
      return `Blocked: generated skill contained unsafe code`;
    }
  }

  // Extract the skill name from the generated code
  const nameMatch = code.match(/export const name = ['"]([^'"]+)['"]/);
  const skillName = nameMatch ? nameMatch[1] : `skill-${Date.now()}`;
  const filename = `${skillName.replace(/[^a-z0-9-]/g, '-')}.mjs`;

  // Write the new skill
  await writeFile(join(SKILLS_DIR, filename), code, 'utf-8');

  // Validate by trying to import it
  try {
    const mod = await import(pathToFileURL(join(SKILLS_DIR, filename)).href + `?t=${Date.now()}`);
    const skill = mod.default || mod;
    if (!skill.name || !skill.execute) {
      const { unlink } = await import('fs/promises');
      await unlink(join(SKILLS_DIR, filename));
      ctx.addEvent('error', 'system', `Self-improve validation failed: skill missing name or execute export. File deleted.`);
      return `Generated skill was invalid (missing exports) and was removed.`;
    }
  } catch (importErr) {
    const { unlink } = await import('fs/promises');
    await unlink(join(SKILLS_DIR, filename));
    ctx.addEvent('error', 'system', `Self-improve validation failed: ${importErr.message}. File deleted.`);
    return `Generated skill had errors and was removed: ${importErr.message}`;
  }

  ctx.addEvent('skill', 'agent', `Self-improvement: created new skill "${skillName}" (${filename})`, {
    skill: 'self-improve',
    created_skill: skillName,
    filename
  });

  // Trigger a skill reload
  const { reloadSkills } = await import('../skills.mjs');
  await reloadSkills();

  return `Created new skill: ${skillName}`;
}

export default { name, description, execute };
