import { z } from 'zod';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { config } from '../../config.js';
import { runCommand } from '../../lib/runCommand.js';
import { errorResult, jsonResult, toErrorMessage } from '../shared.js';
import { requirePhpBackend } from './requireLaravel.js';

/**
 * Composer helpers shared by Laravel and CodeIgniter (both are Composer-based).
 * Mirrors `add_dependency` but is explicitly for PHP packages.
 */
export function registerComposerTools(server: McpServer): void {
  server.registerTool(
    'composer_require',
    {
      title: 'Composer Require',
      description:
        'Add a Composer dependency to the detected PHP backend (Laravel or CodeIgniter). Equivalent to `composer require`.',
      inputSchema: {
        packages: z.array(z.string().min(1)).min(1).describe('Packagist package names, e.g. ["laravel/sanctum"].'),
        dev: z.boolean().optional().default(false).describe('Install into require-dev (--dev).'),
      },
    },
    async ({ packages, dev }) => {
      try {
        const backend = requirePhpBackend();
        const args = ['require', ...(dev ? ['--dev'] : []), ...packages, '--no-interaction'];
        const result = await runCommand('composer', args, {
          cwd: backend.root,
          timeoutMs: config.scaffoldCommandTimeoutMs,
        });
        return jsonResult({ adapter: backend.label, packages, dev, ...result });
      } catch (error) {
        return errorResult(toErrorMessage(error));
      }
    },
  );

  server.registerTool(
    'composer_remove',
    {
      title: 'Composer Remove',
      description:
        'Remove a Composer dependency from the detected PHP backend (Laravel or CodeIgniter). Requires confirm: true.',
      inputSchema: {
        packages: z.array(z.string().min(1)).min(1).describe('Packagist package names to remove.'),
        confirm: z
          .literal(true)
          .describe('Must be exactly true; removing dependencies is a deliberate opt-in.'),
      },
    },
    async ({ packages, confirm }) => {
      if (!confirm) return errorResult('confirm: true is required to run composer_remove.');
      try {
        const backend = requirePhpBackend();
        const result = await runCommand('composer', ['remove', ...packages, '--no-interaction'], {
          cwd: backend.root,
          timeoutMs: config.scaffoldCommandTimeoutMs,
        });
        return jsonResult({ adapter: backend.label, packages, ...result });
      } catch (error) {
        return errorResult(toErrorMessage(error));
      }
    },
  );
}
