import fs from 'node:fs';
import path from 'node:path';
import { z } from 'zod';
import { config } from '../../config.js';
import { runCommand } from '../../lib/runCommand.js';
import { kebabCase, pascalCase } from '../../lib/strings.js';
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
import { requireCodeIgniter } from './requireCodeIgniter.js';
function pluralize(word) {
    const lower = word.toLowerCase();
    if (lower.endsWith('ies'))
        return word;
    if (lower.endsWith('y') && !/[aeiou]y$/i.test(word))
        return `${word.slice(0, -1)}ies`;
    if (/(s|x|z|ch|sh)$/i.test(word))
        return `${word}es`;
    if (lower.endsWith('s'))
        return word;
    return `${word}s`;
}
export function registerGenerateCodeIgniterResourceTool(server) {
    server.registerTool('generate_codeigniter_resource', {
        title: 'Generate CodeIgniter Resource',
        description: 'One-shot scaffold of a full CodeIgniter 4 resource: model + migration + seeder + ResourceController, ' +
            'then wire the route in app/Config/Routes.php. Supports an optional API version path prefix.',
        inputSchema: {
            name: z
                .string()
                .min(1)
                .describe('Resource name, e.g. "Post" or "blog_post". Converted to PascalCase for the model/controller.'),
            migrate: z
                .boolean()
                .optional()
                .default(false)
                .describe('If true, run `php spark migrate` after scaffolding. Requires a configured database.'),
            apiVersion: z
                .string()
                .optional()
                .describe('Optional API version prefix for the route, e.g. "v1" → resource at /v1/{name}.'),
            resourceController: z
                .boolean()
                .optional()
                .default(true)
                .describe('If true (default), generate a ResourceController via spark --resource.'),
        },
    }, async ({ name, migrate, apiVersion, resourceController }) => {
        try {
            const ci = requireCodeIgniter();
            const model = pascalCase(name);
            const controller = `${model}Controller`;
            const routeName = kebabCase(pluralize(model));
            const versionPrefix = apiVersion?.replace(/^\/+|\/+$/g, '') || '';
            const resourcePath = versionPrefix ? `${versionPrefix}/${routeName}` : routeName;
            const steps = [];
            const modelResult = await runCommand('php', ['spark', 'make:model', model, '--no-interaction'], {
                cwd: ci.root,
                timeoutMs: config.scaffoldCommandTimeoutMs,
            });
            steps.push({ step: 'make:model', exitCode: modelResult.exitCode, failed: modelResult.failed, output: modelResult.output });
            const migrationResult = await runCommand('php', ['spark', 'make:migration', `create_${kebabCase(pluralize(model))}_table`, '--no-interaction'], { cwd: ci.root, timeoutMs: config.scaffoldCommandTimeoutMs });
            steps.push({
                step: 'make:migration',
                exitCode: migrationResult.exitCode,
                failed: migrationResult.failed,
                output: migrationResult.output,
            });
            const seederResult = await runCommand('php', ['spark', 'make:seeder', `${model}Seeder`, '--no-interaction'], {
                cwd: ci.root,
                timeoutMs: config.scaffoldCommandTimeoutMs,
            });
            steps.push({
                step: 'make:seeder',
                exitCode: seederResult.exitCode,
                failed: seederResult.failed,
                output: seederResult.output,
            });
            const controllerArgs = ['spark', 'make:controller', controller, '--no-interaction'];
            if (resourceController !== false)
                controllerArgs.splice(3, 0, '--resource');
            const controllerResult = await runCommand('php', controllerArgs, {
                cwd: ci.root,
                timeoutMs: config.scaffoldCommandTimeoutMs,
            });
            steps.push({
                step: 'make:controller',
                exitCode: controllerResult.exitCode,
                failed: controllerResult.failed,
                output: controllerResult.output,
            });
            const routesFile = path.join(ci.root, 'app', 'Config', 'Routes.php');
            const routeLine = `$routes->resource('${resourcePath}', ['controller' => '\\App\\Controllers\\${controller}']);`;
            const routeWired = wireRoute(routesFile, routeLine);
            steps.push({ step: 'wire-route', routesFile, routeLine, wired: routeWired });
            let migrateResult = null;
            if (migrate) {
                migrateResult = await runCommand('php', ['spark', 'migrate', '--no-interaction'], {
                    cwd: ci.root,
                    timeoutMs: config.scaffoldCommandTimeoutMs,
                });
                steps.push({
                    step: 'migrate',
                    exitCode: migrateResult.exitCode,
                    failed: migrateResult.failed,
                    output: migrateResult.output,
                });
            }
            return jsonResult({
                model,
                controller,
                apiVersion: versionPrefix || null,
                route: `resource /${resourcePath}`,
                resourceController: resourceController !== false,
                routesFile,
                routeWired,
                steps,
            });
        }
        catch (error) {
            return errorResult(toErrorMessage(error));
        }
    });
}
function wireRoute(routesFile, routeLine) {
    fs.mkdirSync(path.dirname(routesFile), { recursive: true });
    if (!fs.existsSync(routesFile)) {
        fs.writeFileSync(routesFile, `<?php\n\nuse CodeIgniter\\Router\\RouteCollection;\n\n/**\n * @var RouteCollection $routes\n */\n\n${routeLine}\n`);
        return true;
    }
    const existing = fs.readFileSync(routesFile, 'utf8');
    if (existing.includes(routeLine.trim()))
        return false;
    let next = existing;
    if (!/use\s+CodeIgniter\\Router\\RouteCollection\s*;/.test(next)) {
        if (next.startsWith('<?php')) {
            next = next.replace('<?php', "<?php\n\nuse CodeIgniter\\Router\\RouteCollection;");
        }
        else {
            next = `<?php\n\nuse CodeIgniter\\Router\\RouteCollection;\n\n${next}`;
        }
    }
    fs.writeFileSync(routesFile, `${next.trimEnd()}\n${routeLine}\n`);
    return true;
}
//# sourceMappingURL=generateCodeIgniterResource.js.map