import type { ModelClient } from '../../models/types.js';
import type { Tool, ToolResult } from '../types.js';

interface ImageAnalyzeArgs {
  url?: string;
  data?: string;
  media_type?: string;
  prompt?: string;
}

const DEFAULT_PROMPT = 'Describe this image in detail.';

const VALID_MEDIA_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
  return {
    name: 'image.analyze',
    description: 'Analyze an image using a vision model. Accepts a URL or base64-encoded image data. Returns a text description or analysis based on the provided prompt.',
    inputSchema: {
      type: 'object',
      properties: {
        url: {
          type: 'string',
          description: 'URL of the image to analyze',
        },
        data: {
          type: 'string',
          description: 'Base64-encoded image data (alternative to url)',
        },
        media_type: {
          type: 'string',
          description:
            'MIME type of the image (required when using data). One of: image/jpeg, image/png, image/gif, image/webp',
        },
        prompt: {
          type: 'string',
          description:
            'What to analyze or describe about the image. Default: "Describe this image in detail."',
        },
      },
      required: [],
    },
    execute: async (rawArgs: unknown): Promise<ToolResult> => {
      try {
        const args = rawArgs as ImageAnalyzeArgs;

        if (!args.url && !args.data) {
          return {
            success: false,
            output: '',
            error: 'Either "url" or "data" must be provided',
          };
        }

        if (args.url && args.data) {
          return {
            success: false,
            output: '',
            error: 'Cannot provide both "url" and "data" - choose one',
          };
        }

        if (args.data && !args.media_type) {
          return {
            success: false,
            output: '',
            error: 'media_type is required when providing data',
          };
        }

        if (args.media_type && !VALID_MEDIA_TYPES.includes(args.media_type)) {
          return {
            success: false,
            output: '',
            error: `Invalid media_type: ${args.media_type}. Must be one of: ${VALID_MEDIA_TYPES.join(', ')}`,
          };
        }

        const prompt = args.prompt || DEFAULT_PROMPT;

        const imageSource = args.url
          ? {
            type: 'url' as const,
            media_type: args.media_type || 'image/jpeg',
            url: args.url,
          }
          : {
            type: 'base64' as const,
            media_type: args.media_type!,
            data: args.data,
          };

        const message = {
          role: 'user' as const,
          content: [
            { type: 'text' as const, text: prompt },
            { type: 'image' as const, source: imageSource },
          ],
        };

        const response = await modelClient.chat({
          messages: [message],
          system:
            'You are a vision assistant. Analyze the provided image according to the user\'s request. Provide detailed, helpful descriptions.',
          maxTokens: 1024,
        });

        return {
          success: true,
          output: response.content,
        };
      } catch (error) {
        return {
          success: false,
          output: '',
          error: error instanceof Error ? error.message : String(error),
        };
      }
    },
  };
}
