typedef ToolHandler =
    Future<Map<String, dynamic>> Function(Map<String, dynamic> args);

/// 工具常量
const _toolNameCreateCalendar = 'create_calendar_event';
const _defaultTimezone = 'Asia/Shanghai';
const _defaultEventColor = '#4F46E5';
const _defaultSourceType = 'agentGenerated';
const _titleMinLength = 1;
const _titleMaxLength = 100;

class ToolDefinition {
  final String name;
  final String description;
  final Map<String, dynamic> parameters;
  final ToolHandler handler;

  ToolDefinition({
    required this.name,
    required this.description,
    required this.parameters,
    required this.handler,
  });
}

class ToolRegistry {
  static final Map<String, ToolDefinition> _tools = {};
  static bool _initialized = false;

  static void initialize() {
    if (_initialized) return;

    _tools[_toolNameCreateCalendar] = ToolDefinition(
      name: _toolNameCreateCalendar,
      description: '创建一个日历事件或待办事项',
      parameters: {
        'type': 'object',
        'properties': {
          'title': {
            'type': 'string',
            'description': '事件标题',
            'minLength': _titleMinLength,
            'maxLength': _titleMaxLength,
          },
          'description': {'type': 'string', 'description': '事件描述'},
          'startAt': {
            'type': 'string',
            'format': 'date-time',
            'description': '开始时间 (ISO8601)',
          },
          'endAt': {
            'type': 'string',
            'format': 'date-time',
            'description': '结束时间 (ISO8601)',
          },
          'timezone': {'type': 'string', 'default': _defaultTimezone},
          'location': {'type': 'string'},
          'notes': {'type': 'string'},
        },
        'required': ['title', 'startAt'],
      },
      handler: _handleCreateCalendarEvent,
    );

    _initialized = true;
  }

  static Future<Map<String, dynamic>> _handleCreateCalendarEvent(
    Map<String, dynamic> args,
  ) async {
    final eventId = 'evt_${DateTime.now().millisecondsSinceEpoch}';
    return {
      'eventId': eventId,
      'ok': true,
      'message': '日程已创建',
      'title': args['title'],
      'description': args['description'],
      'startAt': args['startAt'],
      'endAt': args['endAt'],
      'timezone': args['timezone'] ?? _defaultTimezone,
      'location': args['location'],
      'color': _defaultEventColor,
      'sourceType': _defaultSourceType,
    };
  }

  static ToolDefinition? getTool(String name) => _tools[name];
  static List<ToolDefinition> getAllTools() => _tools.values.toList();

  static Future<Map<String, dynamic>> execute(
    String toolName,
    Map<String, dynamic> args,
  ) async {
    final tool = _tools[toolName];
    if (tool == null) throw ToolNotFoundException('Tool not found: $toolName');
    return tool.handler(args);
  }

  static ToolValidationResult validateArgs(
    String toolName,
    Map<String, dynamic> args,
  ) {
    final tool = _tools[toolName];
    if (tool == null) {
      return ToolValidationResult(
        ok: false,
        error: 'Tool not found: $toolName',
      );
    }

    final required = tool.parameters['required'] as List<dynamic>? ?? [];
    final missing = <String>[];
    for (final field in required) {
      if (!args.containsKey(field) || args[field] == null) {
        missing.add(field as String);
      }
    }

    if (missing.isNotEmpty) {
      return ToolValidationResult(
        ok: false,
        error: 'Missing required fields: ${missing.join(', ')}',
      );
    }
    return ToolValidationResult(ok: true);
  }
}

class ToolNotFoundException implements Exception {
  final String message;
  ToolNotFoundException(this.message);
  @override
  String toString() => 'ToolNotFoundException: $message';
}

class ToolValidationResult {
  final bool ok;
  final String? error;
  ToolValidationResult({required this.ok, this.error});
}
