// tools/spec-templates.ts — Handlers for list_templates and apply_template tools.
import { mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { listTemplates, findTemplateWithCustom, renderTemplate, findMissingRequired, } from '../engine/spec-templates/index.js';
/**
 * Returns the list of available spec templates, optionally filtered.
 */
export async function handleListTemplates(args) {
    try {
        const { result, warnings } = await listTemplates(args.category, args.search, args.complexityScore);
        const lines = [
            '# Available Spec Templates',
            '',
            `Found **${result.total}** template${result.total === 1 ? '' : 's'}${result.filteredBy !== undefined ? ` (filtered by: ${result.filteredBy})` : ''}.`,
            '',
        ];
        if (result.templates.length === 0) {
            lines.push('No templates match the given filters. Try removing filters to see all templates.');
        }
        else {
            for (const t of result.templates) {
                lines.push(`## ${t.name} (\`${t.id}\`)`);
                lines.push(`- **Category:** ${t.category}${t.subcategory !== undefined ? ` (${t.subcategory})` : ''}`);
                lines.push(`- **Complexity:** ${t.complexityScore}`);
                lines.push(`- **Criteria:** ${t.criteriaCount}`);
                lines.push(`- **Description:** ${t.description}`);
                lines.push(`- **Tags:** ${t.tags.join(', ')}`);
                lines.push(`- **Variables:** ${t.variableCount} total, ${t.requiredVariableCount} required`);
                lines.push('');
            }
        }
        if (warnings.length > 0) {
            lines.push('### Custom Template Warnings');
            for (const w of warnings) {
                lines.push(`- **${w.file}**: ${w.error}`);
            }
            lines.push('');
        }
        lines.push('---');
        lines.push('Use `apply_template` with a template `id` to create a spec from a template.');
        lines.push('Custom templates: place JSON files in `data/global/spec-templates/custom/`.');
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: `Error listing templates: ${message}` }],
            isError: true,
        };
    }
}
/**
 * Applies a template to create HU.md + FICHA-TECNICA.md + PROGRESS.md.
 */
export async function handleApplyTemplate(args) {
    try {
        const template = await findTemplateWithCustom(args.templateId);
        if (template === undefined) {
            return {
                content: [
                    {
                        type: 'text',
                        text: `Template not found: "${args.templateId}". Use list_templates to see available templates.`,
                    },
                ],
                isError: true,
            };
        }
        const missingRequired = findMissingRequired(template, args.variables);
        if (missingRequired.length > 0) {
            return {
                content: [
                    {
                        type: 'text',
                        text: buildMissingVariablesMessage(missingRequired, template.variables),
                    },
                ],
                isError: true,
            };
        }
        const rendered = renderTemplate(template, args.variables, args.includeCriteria);
        const outputDir = resolveOutputDir(args);
        await mkdir(outputDir, { recursive: true });
        const specPath = join(outputDir, 'HU.md');
        const fichaTecnicaPath = join(outputDir, 'FICHA-TECNICA.md');
        const progressPath = join(outputDir, 'PROGRESS.md');
        await writeFile(specPath, rendered.hu, 'utf-8');
        await writeFile(fichaTecnicaPath, rendered.fichaTecnica, 'utf-8');
        await writeFile(progressPath, rendered.progress, 'utf-8');
        const result = {
            templateId: template.id,
            templateName: template.name,
            complexityScore: template.complexityScore,
            specPath,
            fichaTecnicaPath,
            progressPath,
            variablesApplied: args.variables.length,
            criteriaIncluded: rendered.criteriaIncluded,
            criteriaTotal: rendered.criteriaTotal,
            missingRequired: [],
            warnings: rendered.warnings,
            message: buildSuccessMessage(template.name, outputDir),
        };
        return {
            content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
        };
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: `Error applying template: ${message}` }],
            isError: true,
        };
    }
}
/**
 * Resolves the output directory for the spec files.
 */
function resolveOutputDir(args) {
    if (args.outputDir !== undefined && args.outputDir.trim().length > 0) {
        return args.outputDir.trim();
    }
    const feature = args.feature?.trim();
    const featureSlug = feature !== undefined && feature.length > 0 ? slugify(feature) : '_general';
    return join(args.projectPath, 'planu', 'specs', featureSlug, slugify(args.templateId));
}
/**
 * Converts a string to a URL-safe slug.
 */
function slugify(text) {
    return text
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-+|-+$/g, '')
        .slice(0, 60);
}
/**
 * Builds a user-friendly error message for missing required variables.
 */
function buildMissingVariablesMessage(missingKeys, definitions) {
    const lines = ['Missing required template variables:', ''];
    for (const key of missingKeys) {
        const def = definitions.find((d) => d.key === key);
        if (def !== undefined) {
            lines.push(`- **${def.label}** (key: \`${key}\`): ${def.description}`);
            lines.push(`  Example: "${def.example}"`);
        }
        else {
            lines.push(`- \`${key}\``);
        }
    }
    lines.push('');
    lines.push('Provide all required variables in the `variables` array and try again.');
    return lines.join('\n');
}
/**
 * Builds the success message after a template is applied.
 */
function buildSuccessMessage(templateName, outputDir) {
    return (`Template "${templateName}" applied successfully.\n` +
        `Files created in: ${outputDir}\n` +
        'Next steps:\n' +
        '1. Review and customize HU.md acceptance criteria\n' +
        '2. Update FICHA-TECNICA.md with project-specific details\n' +
        '3. Run create_spec or update_status once the spec is approved');
}
//# sourceMappingURL=spec-templates.js.map