import { generateRefinedInstructions, refineInstructions } from '../refined-instructions.mjs';

export const name = 'create-file';
export const description = 'Create a file (code, text, HTML)';

function sanitizeFilename(name) {
  return String(name || '')
    .trim()
    .replace(/[^a-zA-Z0-9._-]/g, '-')
    .replace(/-+/g, '-')
    .replace(/^-|-$/g, '')
    .slice(0, 80);
}

export async function execute(ctx) {
  const topic = ctx.args?.topic || 'something interesting and creative';
  const requestedFilenameRaw = ctx.args?.filename || '';
  const requestedFilename = sanitizeFilename(requestedFilenameRaw);
  const requestedExt = requestedFilename.includes('.') ? requestedFilename.split('.').pop().toLowerCase() : '';
  const forceSvg = requestedExt === 'svg' || String(ctx.args?.format || '').toLowerCase() === 'svg';

  // Run through the Communicator → Refiner pipeline so complex requests get
  // clear, detailed instructions before we generate the file content.
  // Skip for SVG requests (tightly-constrained format where extra prose hurts).
  let refinedBlock = topic;
  if (!forceSvg) {
    try {
      const deps = { askLLM: ctx.askLLM, pickModel: ctx.pickModel };
      const communicated = await generateRefinedInstructions(topic, deps);
      refinedBlock = await refineInstructions(communicated, deps);
    } catch {
      // Fall back to raw topic on error
    }
  }

  const prompt = `You are an autonomous AI agent with creative abilities.

Topic/request:
${refinedBlock}

Create a self-contained file. Pick the most appropriate format:
- An HTML page with embedded CSS/JS (for visual/interactive things)
- A plain text file (for writing, poetry, essays)
- A code file (for utilities or tools)
${forceSvg ? '- An SVG file when asked for logos/icons/graphics.' : ''}
${requestedFilename ? `\nRequired filename: ${requestedFilename}` : ''}
${forceSvg ? '\nCRITICAL: Output must be valid SVG markup only, starting with <svg and ending with </svg>.' : ''}

Respond with ONLY the file content, no explanation. Start your response with a comment or HTML comment indicating the filename, like:
<!-- filename: my-creation.html -->
or
// filename: my-tool.js`;

  let response = await ctx.askLLM(prompt, { model: ctx.pickModel('build') });

  // Strip markdown code fences if Claude wrapped the response
  response = response.replace(/^```(?:\w+)?\s*\n?/i, '').replace(/\n?\s*```\s*$/, '').trim();

  // Extract filename from first line
  const filenameMatch = response.match(/filename:\s*([^\s>*]+)/i);
  const inferredFilename = filenameMatch ? sanitizeFilename(filenameMatch[1]) : '';
  const filename = requestedFilename || inferredFilename || (forceSvg ? `logo-${Date.now()}.svg` : `creation-${Date.now()}.html`);

  // Remove the filename comment line from content
  let content = response.replace(/^.*filename:.*\n?/i, '').trim();
  if (forceSvg) {
    // Force valid SVG payload when explicitly requested.
    const svgMatch = content.match(/<svg[\s\S]*<\/svg>/i);
    if (svgMatch) content = svgMatch[0].trim();
  }
  if (!content) return 'Skipped: generated content was empty.';

  const written = await ctx.writeOutputFile(filename, content);
  const actualName = written?.name || filename;
  return `Created: ${actualName}`;
}

export default { name, description, execute };
