import { z } from 'zod';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import type { NotionClient } from '../clients/notion.js';

// Zod schemas
const SearchSchema = z.object({
  query: z.string().optional().describe('Search query text'),
  filter_type: z
    .enum(['page', 'database'])
    .optional()
    .describe('Filter by object type (page or database)'),
  sort_direction: z
    .enum(['ascending', 'descending'])
    .optional()
    .describe('Sort direction for last_edited_time'),
  page_size: z.number().min(1).max(100).optional().describe('Number of results to return'),
  start_cursor: z.string().optional().describe('Pagination cursor'),
});

const SearchAllSchema = z.object({
  query: z.string().optional().describe('Search query text'),
  filter_type: z.enum(['page', 'database']).optional().describe('Filter by object type'),
  sort_direction: z.enum(['ascending', 'descending']).optional(),
});

const SearchPagesSchema = z.object({
  query: z.string().optional().describe('Search query text'),
  sort_direction: z.enum(['ascending', 'descending']).optional(),
  page_size: z.number().min(1).max(100).optional(),
  start_cursor: z.string().optional(),
});

const SearchDatabasesSchema = z.object({
  query: z.string().optional().describe('Search query text'),
  sort_direction: z.enum(['ascending', 'descending']).optional(),
  page_size: z.number().min(1).max(100).optional(),
  start_cursor: z.string().optional(),
});

export function getTools(client: NotionClient): Tool[] {
  return [
    {
      name: 'notion_search',
      description:
        'Search all pages and databases accessible to the integration. Supports full-text search, filtering by object type, and sorting by last edit time.',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query text (searches titles and content)',
          },
          filter_type: {
            type: 'string',
            enum: ['page', 'database'],
            description: 'Filter by object type (page or database)',
          },
          sort_direction: {
            type: 'string',
            enum: ['ascending', 'descending'],
            description: 'Sort direction for last_edited_time',
          },
          page_size: {
            type: 'number',
            description: 'Number of results to return (max 100)',
          },
          start_cursor: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
    },
    {
      name: 'notion_search_all',
      description:
        'Search all pages and databases with auto-pagination. Returns ALL matching results.',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query text',
          },
          filter_type: {
            type: 'string',
            enum: ['page', 'database'],
            description: 'Filter by object type',
          },
          sort_direction: {
            type: 'string',
            enum: ['ascending', 'descending'],
            description: 'Sort direction',
          },
        },
      },
    },
    {
      name: 'notion_search_pages',
      description:
        'Search only pages (not databases). Convenient shortcut for searching pages specifically.',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query text',
          },
          sort_direction: {
            type: 'string',
            enum: ['ascending', 'descending'],
            description: 'Sort direction',
          },
          page_size: {
            type: 'number',
            description: 'Number of results to return',
          },
          start_cursor: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
    },
    {
      name: 'notion_search_databases',
      description: 'Search only databases (not pages). Returns matching database results.',
      inputSchema: {
        type: 'object',
        properties: {
          query: {
            type: 'string',
            description: 'Search query text',
          },
          sort_direction: {
            type: 'string',
            enum: ['ascending', 'descending'],
            description: 'Sort direction',
          },
          page_size: {
            type: 'number',
            description: 'Number of results to return',
          },
          start_cursor: {
            type: 'string',
            description: 'Pagination cursor',
          },
        },
      },
    },
  ];
}

export async function handleSearchTool(
  toolName: string,
  args: any,
  client: NotionClient
): Promise<any> {
  switch (toolName) {
    case 'notion_search': {
      const validated = SearchSchema.parse(args);
      const params: any = {};

      if (validated.query) {
        params.query = validated.query;
      }
      if (validated.filter_type) {
        params.filter = { value: validated.filter_type, property: 'object' };
      }
      if (validated.sort_direction) {
        params.sort = {
          direction: validated.sort_direction,
          timestamp: 'last_edited_time',
        };
      }
      if (validated.page_size) {
        params.page_size = validated.page_size;
      }
      if (validated.start_cursor) {
        params.start_cursor = validated.start_cursor;
      }

      const results = await client.search(params);
      return results;
    }

    case 'notion_search_all': {
      const validated = SearchAllSchema.parse(args);
      const params: any = {};

      if (validated.query) {
        params.query = validated.query;
      }
      if (validated.filter_type) {
        params.filter = { value: validated.filter_type, property: 'object' };
      }
      if (validated.sort_direction) {
        params.sort = {
          direction: validated.sort_direction,
          timestamp: 'last_edited_time',
        };
      }

      const allResults = [];
      for await (const result of client.searchAll(params)) {
        allResults.push(result);
      }
      return { object: 'list', results: allResults, has_more: false, next_cursor: null };
    }

    case 'notion_search_pages': {
      const validated = SearchPagesSchema.parse(args);
      const params: any = {
        filter: { value: 'page', property: 'object' },
      };

      if (validated.query) params.query = validated.query;
      if (validated.sort_direction) {
        params.sort = {
          direction: validated.sort_direction,
          timestamp: 'last_edited_time',
        };
      }
      if (validated.page_size) params.page_size = validated.page_size;
      if (validated.start_cursor) params.start_cursor = validated.start_cursor;

      const results = await client.search(params);
      return results;
    }

    case 'notion_search_databases': {
      const validated = SearchDatabasesSchema.parse(args);
      const params: any = {
        filter: { value: 'database', property: 'object' },
      };

      if (validated.query) params.query = validated.query;
      if (validated.sort_direction) {
        params.sort = {
          direction: validated.sort_direction,
          timestamp: 'last_edited_time',
        };
      }
      if (validated.page_size) params.page_size = validated.page_size;
      if (validated.start_cursor) params.start_cursor = validated.start_cursor;

      const results = await client.search(params);
      return results;
    }

    default:
      throw new Error(`Unknown search tool: ${toolName}`);
  }
}
