import { AuthType, EToolResources } from 'librechat-data-provider';
import type { TPlugin } from 'librechat-data-provider';
import { filterUniquePlugins, checkPluginAuth, getToolkitKey } from './format';

describe('format.ts helper functions', () => {
  describe('filterUniquePlugins', () => {
    it('should return empty array when plugins is undefined', () => {
      const result = filterUniquePlugins(undefined);
      expect(result).toEqual([]);
    });

    it('should return empty array when plugins is empty', () => {
      const result = filterUniquePlugins([]);
      expect(result).toEqual([]);
    });

    it('should filter out duplicate plugins based on pluginKey', () => {
      const plugins: TPlugin[] = [
        { name: 'Plugin1', pluginKey: 'key1', description: 'First plugin' },
        { name: 'Plugin2', pluginKey: 'key2', description: 'Second plugin' },
        { name: 'Plugin1 Duplicate', pluginKey: 'key1', description: 'Duplicate of first' },
        { name: 'Plugin3', pluginKey: 'key3', description: 'Third plugin' },
      ];

      const result = filterUniquePlugins(plugins);
      expect(result).toHaveLength(3);
      expect(result[0].pluginKey).toBe('key1');
      expect(result[1].pluginKey).toBe('key2');
      expect(result[2].pluginKey).toBe('key3');
      // The first occurrence should be kept
      expect(result[0].name).toBe('Plugin1');
    });

    it('should handle plugins with identical data', () => {
      const plugin: TPlugin = { name: 'Plugin', pluginKey: 'key', description: 'Test' };
      const plugins: TPlugin[] = [plugin, plugin, plugin];

      const result = filterUniquePlugins(plugins);
      expect(result).toHaveLength(1);
      expect(result[0]).toEqual(plugin);
    });
  });

  describe('checkPluginAuth', () => {
    const originalEnv = process.env;

    beforeEach(() => {
      process.env = { ...originalEnv };
    });

    afterEach(() => {
      process.env = originalEnv;
    });

    it('should return false when plugin is undefined', () => {
      const result = checkPluginAuth(undefined);
      expect(result).toBe(false);
    });

    it('should return false when authConfig is undefined', () => {
      const plugin: TPlugin = { name: 'Test', pluginKey: 'test', description: 'Test plugin' };
      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should return false when authConfig is empty array', () => {
      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [],
      };
      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should return true when all required auth fields have valid env values', () => {
      process.env.API_KEY = 'valid-key';
      process.env.SECRET_KEY = 'valid-secret';

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [
          { authField: 'API_KEY', label: 'API Key', description: 'API Key' },
          { authField: 'SECRET_KEY', label: 'Secret Key', description: 'Secret Key' },
        ],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(true);
    });

    it('should return false when any required auth field is missing', () => {
      process.env.API_KEY = 'valid-key';
      // SECRET_KEY is not set

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [
          { authField: 'API_KEY', label: 'API Key', description: 'API Key' },
          { authField: 'SECRET_KEY', label: 'Secret Key', description: 'Secret Key' },
        ],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should return false when auth field value is empty string', () => {
      process.env.API_KEY = '';

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [{ authField: 'API_KEY', label: 'API Key', description: 'API Key' }],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should return false when auth field value is whitespace only', () => {
      process.env.API_KEY = '   ';

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [{ authField: 'API_KEY', label: 'API Key', description: 'API Key' }],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should return false when auth field value is USER_PROVIDED', () => {
      process.env.API_KEY = AuthType.USER_PROVIDED;

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [{ authField: 'API_KEY', label: 'API Key', description: 'API Key' }],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(false);
    });

    it('should handle alternate auth fields with || separator', () => {
      process.env.ALTERNATE_KEY = 'valid-key';

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [
          { authField: 'PRIMARY_KEY||ALTERNATE_KEY', label: 'API Key', description: 'API Key' },
        ],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(true);
    });

    it('should return true when at least one alternate auth field is valid', () => {
      process.env.PRIMARY_KEY = '';
      process.env.ALTERNATE_KEY = 'valid-key';
      process.env.THIRD_KEY = AuthType.USER_PROVIDED;

      const plugin: TPlugin = {
        name: 'Test',
        pluginKey: 'test',
        description: 'Test plugin',
        authConfig: [
          {
            authField: 'PRIMARY_KEY||ALTERNATE_KEY||THIRD_KEY',
            label: 'API Key',
            description: 'API Key',
          },
        ],
      };

      const result = checkPluginAuth(plugin);
      expect(result).toBe(true);
    });
  });

  describe('getToolkitKey', () => {
    it('should return undefined when toolName is undefined', () => {
      const toolkits: TPlugin[] = [
        { name: 'Toolkit1', pluginKey: 'toolkit1', description: 'Test toolkit' },
      ];

      const result = getToolkitKey({ toolkits, toolName: undefined });
      expect(result).toBeUndefined();
    });

    it('should return undefined when toolName is empty string', () => {
      const toolkits: TPlugin[] = [
        { name: 'Toolkit1', pluginKey: 'toolkit1', description: 'Test toolkit' },
      ];

      const result = getToolkitKey({ toolkits, toolName: '' });
      expect(result).toBeUndefined();
    });

    it('should return undefined when no matching toolkit is found', () => {
      const toolkits: TPlugin[] = [
        { name: 'Toolkit1', pluginKey: 'toolkit1', description: 'Test toolkit' },
        { name: 'Toolkit2', pluginKey: 'toolkit2', description: 'Test toolkit' },
      ];

      const result = getToolkitKey({ toolkits, toolName: 'nonexistent_tool' });
      expect(result).toBeUndefined();
    });

    it('should match toolkit when toolName starts with pluginKey', () => {
      const toolkits: TPlugin[] = [
        { name: 'Toolkit1', pluginKey: 'toolkit1', description: 'Test toolkit' },
        { name: 'Toolkit2', pluginKey: 'toolkit2', description: 'Test toolkit' },
      ];

      const result = getToolkitKey({ toolkits, toolName: 'toolkit2_function' });
      expect(result).toBe('toolkit2');
    });

    it('should handle image_edit tools with suffix matching', () => {
      const toolkits: TPlugin[] = [
        { name: 'Image Editor', pluginKey: 'image_edit_v1', description: 'Image editing' },
        { name: 'Image Editor 2', pluginKey: 'image_edit_v2', description: 'Image editing v2' },
      ];

      const result = getToolkitKey({
        toolkits,
        toolName: `${EToolResources.image_edit}_function_v2`,
      });
      expect(result).toBe('image_edit_v2');
    });

    it('should match the first toolkit when multiple matches are possible', () => {
      const toolkits: TPlugin[] = [
        { name: 'Toolkit', pluginKey: 'toolkit', description: 'Base toolkit' },
        { name: 'Toolkit Extended', pluginKey: 'toolkit_extended', description: 'Extended' },
      ];

      const result = getToolkitKey({ toolkits, toolName: 'toolkit_function' });
      expect(result).toBe('toolkit');
    });

    it('should handle empty toolkits array', () => {
      const toolkits: TPlugin[] = [];

      const result = getToolkitKey({ toolkits, toolName: 'any_tool' });
      expect(result).toBeUndefined();
    });

    it('should handle complex plugin keys with underscores', () => {
      const toolkits: TPlugin[] = [
        {
          name: 'Complex Toolkit',
          pluginKey: 'complex_toolkit_with_underscores',
          description: 'Complex',
        },
      ];

      const result = getToolkitKey({
        toolkits,
        toolName: 'complex_toolkit_with_underscores_function',
      });
      expect(result).toBe('complex_toolkit_with_underscores');
    });
  });
});
