import type { FastMCP } from 'fastmcp';
import { UserError } from 'fastmcp';
import { z } from 'zod';
import { getSheetsClient } from '../../clients.js';
import * as SheetsHelpers from '../../googleSheetsApiHelpers.js';

export function register(server: FastMCP) {
  server.addTool({
    name: 'formatCells',
    description:
      "Applies formatting to a range of cells in a spreadsheet. Supports bold, italic, font size, text color, background color, alignment, and number format. Use range '1:1' to format an entire header row, 'A:A' for an entire column, or 'A1:D1' for specific cells. Use numberFormat to control how values are displayed (e.g. as numbers, text, dates) or to clear a format by setting type to 'TEXT'.",
    parameters: z
      .object({
        spreadsheetId: z
          .string()
          .describe(
            'The spreadsheet ID — the long string between /d/ and /edit in a Google Sheets URL.'
          ),
        range: z
          .string()
          .describe(
            'A1 notation range to format. Examples: "Sheet1!A1:D1", "1:1" (entire row 1), "A:A" (entire column A), "B2:E10".'
          ),
        bold: z.boolean().optional().describe('Apply bold text formatting.'),
        italic: z.boolean().optional().describe('Apply italic text formatting.'),
        fontSize: z.number().min(1).optional().describe('Font size in points.'),
        foregroundColor: z.string().optional().describe('Text color as hex (e.g., "#FF0000").'),
        backgroundColor: z
          .string()
          .optional()
          .describe('Cell background color as hex (e.g., "#D9EAD3").'),
        horizontalAlignment: z
          .enum(['LEFT', 'CENTER', 'RIGHT'])
          .optional()
          .describe('Horizontal text alignment.'),
        verticalAlignment: z
          .enum(['TOP', 'MIDDLE', 'BOTTOM'])
          .optional()
          .describe('Vertical text alignment within the cell.'),
        wrapStrategy: z
          .enum(['OVERFLOW_CELL', 'CLIP', 'WRAP'])
          .optional()
          .describe(
            'Text wrap strategy: WRAP wraps to multiple lines, CLIP truncates, OVERFLOW_CELL overflows into adjacent cells.'
          ),
        numberFormat: z
          .object({
            type: z
              .enum([
                'TEXT',
                'NUMBER',
                'PERCENT',
                'CURRENCY',
                'DATE',
                'TIME',
                'DATE_TIME',
                'SCIENTIFIC',
              ])
              .describe(
                'Number format type. Use "TEXT" to treat cells as plain text (also clears any existing date/number format). Use "NUMBER" for general numeric display.'
              ),
            pattern: z
              .string()
              .optional()
              .describe(
                'Optional custom format pattern (e.g., "0.00", "#,##0", "yyyy-MM-dd"). If omitted, the default pattern for the type is used.'
              ),
          })
          .optional()
          .describe(
            'Controls how cell values are displayed. Useful for clearing date formatting (set type to "TEXT") or applying a custom number pattern.'
          ),
      })
      .refine(
        (data) =>
          data.bold !== undefined ||
          data.italic !== undefined ||
          data.fontSize !== undefined ||
          data.foregroundColor !== undefined ||
          data.backgroundColor !== undefined ||
          data.horizontalAlignment !== undefined ||
          data.verticalAlignment !== undefined ||
          data.wrapStrategy !== undefined ||
          data.numberFormat !== undefined,
        { message: 'At least one formatting option must be provided.' }
      ),
    execute: async (args, { log }) => {
      const sheets = await getSheetsClient();
      log.info(`Formatting cells in range "${args.range}" of spreadsheet ${args.spreadsheetId}`);

      try {
        // Build the format object expected by the helper
        const format: Parameters<typeof SheetsHelpers.formatCells>[3] = {};

        if (args.backgroundColor) {
          const rgb = SheetsHelpers.hexToRgb(args.backgroundColor);
          if (!rgb) throw new UserError(`Invalid background color: "${args.backgroundColor}".`);
          format.backgroundColor = rgb;
        }

        const hasTextFormat =
          args.bold !== undefined ||
          args.italic !== undefined ||
          args.fontSize !== undefined ||
          args.foregroundColor !== undefined;

        if (hasTextFormat) {
          format.textFormat = {};
          if (args.bold !== undefined) format.textFormat.bold = args.bold;
          if (args.italic !== undefined) format.textFormat.italic = args.italic;
          if (args.fontSize !== undefined) format.textFormat.fontSize = args.fontSize;
          if (args.foregroundColor) {
            const rgb = SheetsHelpers.hexToRgb(args.foregroundColor);
            if (!rgb) throw new UserError(`Invalid foreground color: "${args.foregroundColor}".`);
            format.textFormat.foregroundColor = rgb;
          }
        }

        if (args.horizontalAlignment) {
          format.horizontalAlignment = args.horizontalAlignment;
        }

        if (args.verticalAlignment) {
          format.verticalAlignment = args.verticalAlignment;
        }

        if (args.wrapStrategy) {
          (format as any).wrapStrategy = args.wrapStrategy;
        }

        if (args.numberFormat) {
          format.numberFormat = args.numberFormat;
        }

        await SheetsHelpers.formatCells(sheets, args.spreadsheetId, args.range, format);

        return `Successfully applied formatting to range "${args.range}".`;
      } catch (error: any) {
        log.error(`Error formatting cells: ${error.message || error}`);
        if (error instanceof UserError) throw error;
        throw new UserError(`Failed to format cells: ${error.message || 'Unknown error'}`);
      }
    },
  });
}
