import { z } from 'zod';
import { readFile } from 'node:fs/promises';
import type { ToolDef, ToolContext } from './types.js';
import { resolveWritePath } from '../write_guard.js';
import { lspManager } from '../lsp/server-manager.js';
import { getDiagnostics } from '../lsp/operations.js';

const LspDiagnosticsInput = z.object({
  file_path: z.string().describe('Path to the file to check for diagnostics'),
});

type InputT = z.infer<typeof LspDiagnosticsInput>;

export const lspDiagnosticsTool: ToolDef<InputT> = {
  name: 'lsp_diagnostics',
  description: 'Get TypeScript/JavaScript diagnostics (errors, warnings) for a file. Returns diagnostic messages with severity and location.',
  inputSchema: LspDiagnosticsInput,
  jsonSchema: {
    type: 'function',
    function: {
      name: 'lsp_diagnostics',
      description: 'Get TypeScript/JavaScript diagnostics for a file',
      parameters: {
        type: 'object',
        properties: {
          file_path: { type: 'string', description: 'Path to the file' },
        },
        required: ['file_path'],
      },
    },
  },

  async execute(input: InputT, projectRoot: string, _context: ToolContext): Promise<unknown> {
    const resolved = await resolveWritePath(projectRoot, input.file_path);
    const content = await readFile(resolved, 'utf8');
    const client = await lspManager.getClient(resolved);
    if (!client) return { error: 'Unsupported file type for LSP diagnostics' };

    const diagnostics = await getDiagnostics(client, resolved, content);
    if (diagnostics.length === 0) return { result: 'No diagnostics found.' };

    const lines = diagnostics.map((d) => {
      const sev = ['', 'error', 'warning', 'info', 'hint'][d.severity] ?? 'unknown';
      return `[${sev}] line ${d.range.start.line + 1}:${d.range.start.character + 1} - ${d.message}`;
    });
    return { result: lines.join('\n') };
  },
};
