import {
  updatePromptGroupSchema,
  validatePromptGroupUpdate,
  safeValidatePromptGroupUpdate,
} from './schemas';

describe('updatePromptGroupSchema', () => {
  describe('allowed fields', () => {
    it('should accept valid name field', () => {
      const result = updatePromptGroupSchema.safeParse({ name: 'Test Group' });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.name).toBe('Test Group');
      }
    });

    it('should accept valid oneliner field', () => {
      const result = updatePromptGroupSchema.safeParse({ oneliner: 'A short description' });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.oneliner).toBe('A short description');
      }
    });

    it('should accept valid category field', () => {
      const result = updatePromptGroupSchema.safeParse({ category: 'testing' });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.category).toBe('testing');
      }
    });

    it('should accept valid projectIds array', () => {
      const result = updatePromptGroupSchema.safeParse({
        projectIds: ['proj1', 'proj2'],
      });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.projectIds).toEqual(['proj1', 'proj2']);
      }
    });

    it('should accept valid removeProjectIds array', () => {
      const result = updatePromptGroupSchema.safeParse({
        removeProjectIds: ['proj1'],
      });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.removeProjectIds).toEqual(['proj1']);
      }
    });

    it('should accept valid command field', () => {
      const result = updatePromptGroupSchema.safeParse({ command: 'my-command-123' });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.command).toBe('my-command-123');
      }
    });

    it('should accept null command field', () => {
      const result = updatePromptGroupSchema.safeParse({ command: null });
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.command).toBeNull();
      }
    });

    it('should accept multiple valid fields', () => {
      const input = {
        name: 'Updated Name',
        category: 'new-category',
        oneliner: 'New description',
      };
      const result = updatePromptGroupSchema.safeParse(input);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(input);
      }
    });

    it('should accept empty object', () => {
      const result = updatePromptGroupSchema.safeParse({});
      expect(result.success).toBe(true);
    });
  });

  describe('security - strips sensitive fields', () => {
    it('should reject author field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        author: '507f1f77bcf86cd799439011',
      });
      expect(result.success).toBe(false);
    });

    it('should reject authorName field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        authorName: 'Malicious Author',
      });
      expect(result.success).toBe(false);
    });

    it('should reject _id field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        _id: '507f1f77bcf86cd799439011',
      });
      expect(result.success).toBe(false);
    });

    it('should reject productionId field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        productionId: '507f1f77bcf86cd799439011',
      });
      expect(result.success).toBe(false);
    });

    it('should reject createdAt field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        createdAt: new Date().toISOString(),
      });
      expect(result.success).toBe(false);
    });

    it('should reject updatedAt field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        updatedAt: new Date().toISOString(),
      });
      expect(result.success).toBe(false);
    });

    it('should reject __v field', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Test',
        __v: 999,
      });
      expect(result.success).toBe(false);
    });

    it('should reject multiple sensitive fields in a single request', () => {
      const result = updatePromptGroupSchema.safeParse({
        name: 'Legit Name',
        author: '507f1f77bcf86cd799439011',
        authorName: 'Hacker',
        _id: 'newid123',
        productionId: 'prodid456',
        createdAt: '2020-01-01T00:00:00.000Z',
        __v: 999,
      });
      expect(result.success).toBe(false);
    });
  });

  describe('validation rules', () => {
    it('should reject empty name', () => {
      const result = updatePromptGroupSchema.safeParse({ name: '' });
      expect(result.success).toBe(false);
    });

    it('should reject name exceeding max length', () => {
      const result = updatePromptGroupSchema.safeParse({ name: 'a'.repeat(256) });
      expect(result.success).toBe(false);
    });

    it('should reject oneliner exceeding max length', () => {
      const result = updatePromptGroupSchema.safeParse({ oneliner: 'a'.repeat(501) });
      expect(result.success).toBe(false);
    });

    it('should reject category exceeding max length', () => {
      const result = updatePromptGroupSchema.safeParse({ category: 'a'.repeat(101) });
      expect(result.success).toBe(false);
    });

    it('should reject command with invalid characters (uppercase)', () => {
      const result = updatePromptGroupSchema.safeParse({ command: 'MyCommand' });
      expect(result.success).toBe(false);
    });

    it('should reject command with invalid characters (spaces)', () => {
      const result = updatePromptGroupSchema.safeParse({ command: 'my command' });
      expect(result.success).toBe(false);
    });

    it('should reject command with invalid characters (special)', () => {
      const result = updatePromptGroupSchema.safeParse({ command: 'my_command!' });
      expect(result.success).toBe(false);
    });
  });
});

describe('validatePromptGroupUpdate', () => {
  it('should return validated data for valid input', () => {
    const input = { name: 'Test', category: 'testing' };
    const result = validatePromptGroupUpdate(input);
    expect(result).toEqual(input);
  });

  it('should throw ZodError for invalid input', () => {
    expect(() => validatePromptGroupUpdate({ author: 'malicious-id' })).toThrow();
  });
});

describe('safeValidatePromptGroupUpdate', () => {
  it('should return success true for valid input', () => {
    const result = safeValidatePromptGroupUpdate({ name: 'Test' });
    expect(result.success).toBe(true);
  });

  it('should return success false for invalid input with errors', () => {
    const result = safeValidatePromptGroupUpdate({ author: 'malicious-id' });
    expect(result.success).toBe(false);
    if (!result.success) {
      expect(result.error.errors.length).toBeGreaterThan(0);
    }
  });
});
