import fs from 'node:fs';
import path from 'node:path';
import { z } from 'zod';
import { config } from '../../config.js';
import { detectProject } from '../../lib/frameworks/detect.js';
import { camelCase, kebabCase, pascalCase } from '../../lib/strings.js';
import { errorResult, jsonResult, targetSchema, toErrorMessage } from '../shared.js';
const METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
export function registerGenerateApiRouteTool(server) {
    server.registerTool('generate_api_route', {
        title: 'Generate API Route',
        description: 'Scaffold a backend route + handler for the detected framework: controller + routes/api.php entry for Laravel, controller + Routes.php entry for CodeIgniter, an app/pages API route file for Next.js, or a standalone Express router file otherwise.',
        inputSchema: {
            name: z.string().min(1).describe('Resource/route name, e.g. "posts" or "UserProfile".'),
            method: z.enum(METHODS).optional().default('GET'),
            target: targetSchema,
        },
    }, async ({ name, method, target }) => {
        try {
            const detected = detectProject(config.workspaceRoot);
            const adapter = target === 'frontend'
                ? detected.frontend
                : target === 'backend'
                    ? detected.backend
                    : (detected.backend ?? detected.frontend ?? detected.primary);
            if (!adapter)
                return errorResult(`target "${target}" was requested but no such project was detected.`);
            switch (adapter.kind) {
                case 'laravel':
                    return jsonResult(generateLaravelRoute(adapter.root, name, method));
                case 'codeigniter':
                    return jsonResult(generateCodeIgniterRoute(adapter.root, name, method));
                case 'react':
                    return jsonResult(generateNextApiRoute(adapter.root, name, method));
                default:
                    return jsonResult(generateExpressRoute(adapter.root, name, method));
            }
        }
        catch (error) {
            return errorResult(toErrorMessage(error));
        }
    });
}
function appendUnlessPresent(file, header, line) {
    fs.mkdirSync(path.dirname(file), { recursive: true });
    if (!fs.existsSync(file)) {
        fs.writeFileSync(file, header);
    }
    const existing = fs.readFileSync(file, 'utf8');
    if (!existing.includes(line.trim())) {
        fs.appendFileSync(file, `${line}\n`);
    }
}
function writeIfMissing(file, contents) {
    fs.mkdirSync(path.dirname(file), { recursive: true });
    if (fs.existsSync(file))
        return false;
    fs.writeFileSync(file, contents);
    return true;
}
function generateLaravelRoute(root, name, method) {
    const controllerName = `${pascalCase(name)}Controller`;
    const controllerFile = path.join(root, 'app', 'Http', 'Controllers', `${controllerName}.php`);
    const controllerCreated = writeIfMissing(controllerFile, `<?php

namespace App\\Http\\Controllers;

use Illuminate\\Http\\Request;

class ${controllerName}
{
    public function __invoke(Request $request)
    {
        return response()->json([]);
    }
}
`);
    const routesFile = path.join(root, 'routes', 'api.php');
    appendUnlessPresent(routesFile, `<?php

use Illuminate\\Support\\Facades\\Route;

`, `Route::${method.toLowerCase()}('/${kebabCase(name)}', \\App\\Http\\Controllers\\${controllerName}::class);`);
    return { kind: 'laravel', controllerFile, controllerCreated, routesFile, route: `${method} /api/${kebabCase(name)}` };
}
function generateCodeIgniterRoute(root, name, method) {
    const controllerName = pascalCase(name);
    const controllerFile = path.join(root, 'app', 'Controllers', `${controllerName}.php`);
    const controllerCreated = writeIfMissing(controllerFile, `<?php

namespace App\\Controllers;

class ${controllerName} extends BaseController
{
    public function index()
    {
        return $this->response->setJSON([]);
    }
}
`);
    const routesFile = path.join(root, 'app', 'Config', 'Routes.php');
    appendUnlessPresent(routesFile, `<?php

use CodeIgniter\\Router\\RouteCollection;

/** @var RouteCollection $routes */

`, `$routes->${method.toLowerCase()}('${kebabCase(name)}', '${controllerName}::index');`);
    return { kind: 'codeigniter', controllerFile, controllerCreated, routesFile, route: `${method} /${kebabCase(name)}` };
}
function generateNextApiRoute(root, name, method) {
    const appDir = path.join(root, 'app');
    const srcAppDir = path.join(root, 'src', 'app');
    const pagesDir = path.join(root, 'pages');
    const srcPagesDir = path.join(root, 'src', 'pages');
    const appRoot = fs.existsSync(appDir) ? appDir : fs.existsSync(srcAppDir) ? srcAppDir : null;
    const pagesRoot = fs.existsSync(pagesDir) ? pagesDir : fs.existsSync(srcPagesDir) ? srcPagesDir : null;
    if (appRoot) {
        const file = path.join(appRoot, 'api', kebabCase(name), 'route.ts');
        const created = writeIfMissing(file, `import { NextResponse } from 'next/server';

export async function ${method}() {
  return NextResponse.json({});
}
`);
        return { kind: 'next-app-router', file, created, route: `${method} /api/${kebabCase(name)}` };
    }
    if (pagesRoot) {
        const file = path.join(pagesRoot, 'api', `${kebabCase(name)}.ts`);
        const created = writeIfMissing(file, `import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== '${method}') {
    res.status(405).end();
    return;
  }
  res.status(200).json({});
}
`);
        return { kind: 'next-pages-router', file, created, route: `${method} /api/${kebabCase(name)}` };
    }
    throw new Error('The detected React project has no "app" or "pages" directory, so it has no built-in API routes (this looks like a plain Vite React app, not Next.js). ' +
        'Scaffold a separate backend (Laravel/CodeIgniter/express-api) instead, or use target: "backend" if one already exists.');
}
function generateExpressRoute(root, name, method) {
    const file = path.join(root, 'routes', `${kebabCase(name)}.js`);
    const created = writeIfMissing(file, `import { Router } from 'express';

const router = Router();

router.${method.toLowerCase()}('/', (req, res) => {
  res.json({});
});

export default router;
`);
    const varName = `${camelCase(name)}Router`;
    return {
        kind: 'express',
        file,
        created,
        route: `${method} /api/${kebabCase(name)}`,
        wiring: `Not auto-mounted. Add to your app entry point: import ${varName} from './routes/${kebabCase(name)}.js'; app.use('/api/${kebabCase(name)}', ${varName});`,
    };
}
//# sourceMappingURL=generateApiRoute.js.map