import type { FastMCP } from 'fastmcp';
import { UserError } from 'fastmcp';
import { z } from 'zod';
import { docs_v1 } from 'googleapis';
import { getDocsClient } from '../../clients.js';
import { DocumentIdParameter } from '../../types.js';
import * as GDocsHelpers from '../../googleDocsApiHelpers.js';

const FindAndReplaceParameters = DocumentIdParameter.extend({
  findText: z.string().min(1).describe('The text to search for in the document.'),
  replaceText: z
    .string()
    .describe('The replacement text. Use an empty string to delete all occurrences.'),
  matchCase: z
    .boolean()
    .optional()
    .describe('Whether the search should be case-sensitive. Defaults to false.'),
  tabId: z
    .string()
    .optional()
    .describe('Scope replacement to a specific tab. If omitted, replaces across all tabs.'),
});

export function register(server: FastMCP) {
  server.addTool({
    name: 'findAndReplace',
    description:
      'Replaces all occurrences of a text string throughout the document (or a specific tab). ' +
      'Returns the number of replacements made. Use an empty replaceText to delete all matches.',
    parameters: FindAndReplaceParameters,
    execute: async (args, { log }) => {
      const docs = await getDocsClient();
      log.info(
        `findAndReplace in doc ${args.documentId}: "${args.findText}" → "${args.replaceText}"` +
          `${args.matchCase ? ' (case-sensitive)' : ''}` +
          `${args.tabId ? ` (tab: ${args.tabId})` : ''}`
      );

      try {
        const request: docs_v1.Schema$Request = {
          replaceAllText: {
            containsText: {
              text: args.findText,
              matchCase: args.matchCase ?? false,
            },
            replaceText: args.replaceText,
            ...(args.tabId && { tabsCriteria: { tabIds: [args.tabId] } }),
          },
        };

        const response = await GDocsHelpers.executeBatchUpdate(docs, args.documentId, [request]);
        const changed = response.replies?.[0]?.replaceAllText?.occurrencesChanged ?? 0;

        return `Replaced ${changed} occurrence(s) of "${args.findText}" with "${args.replaceText}".`;
      } catch (error: any) {
        log.error(`Error in findAndReplace for doc ${args.documentId}: ${error.message || error}`);
        if (error instanceof UserError) throw error;
        throw new UserError(`Failed to find and replace: ${error.message || 'Unknown error'}`);
      }
    },
  });
}
