import {
  OIDCAuthorizeDto,
  OIDCTokenDto,
} from '../oidc.dto';

describe('OIDC DTOs', () => {
  describe('OIDCAuthorizeDto', () => {
    it('should validate valid OIDC authorize data', () => {
      const validData = {
        client_id: 'client-123',
        redirect_uri: 'https://example.com/callback',
        scope: 'openid email profile',
        state: 'random-state',
        response_type: 'code',
      };

      const result = OIDCAuthorizeDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should validate authorize data with defaults', () => {
      const validData = {
        client_id: 'client-123',
        redirect_uri: 'https://example.com/callback',
      };

      const result = OIDCAuthorizeDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.client_id).toBe(validData.client_id);
        expect(result.data.redirect_uri).toBe(validData.redirect_uri);
        expect(result.data.scope).toBe('openid email profile');
        expect(result.data.response_type).toBe('code');
        expect(result.data.state).toBeUndefined();
      }
    });

    it('should validate authorize data without state', () => {
      const validData = {
        client_id: 'client-123',
        redirect_uri: 'https://example.com/callback',
        scope: 'openid profile',
        response_type: 'token',
      };

      const result = OIDCAuthorizeDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.state).toBeUndefined();
      }
    });

    it('should reject empty client_id', () => {
      const invalidData = {
        client_id: '',
        redirect_uri: 'https://example.com/callback',
      };

      const result = OIDCAuthorizeDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('client_id');
      }
    });

    it('should reject invalid redirect_uri', () => {
      const invalidData = {
        client_id: 'client-123',
        redirect_uri: 'invalid-url',
      };

      const result = OIDCAuthorizeDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('redirect_uri');
      }
    });

    it('should accept HTTP redirect_uri', () => {
      const validData = {
        client_id: 'client-123',
        redirect_uri: 'http://example.com/callback',
      };

      const result = OIDCAuthorizeDto.safeParse(validData);
      expect(result.success).toBe(true);
    });
  });

  describe('OIDCTokenDto', () => {
    it('should validate valid authorization_code token request', () => {
      const validData = {
        grant_type: 'authorization_code' as const,
        code: 'auth-code-123',
        client_id: 'client-123',
        client_secret: 'client-secret-123',
        redirect_uri: 'https://example.com/callback',
      };

      const result = OIDCTokenDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should validate valid refresh_token token request', () => {
      const validData = {
        grant_type: 'refresh_token' as const,
        refresh_token: 'refresh-token-123',
        client_id: 'client-123',
        client_secret: 'client-secret-123',
      };

      const result = OIDCTokenDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data).toEqual(validData);
      }
    });

    it('should reject invalid grant_type', () => {
      const invalidData = {
        grant_type: 'invalid_grant' as any,
        code: 'auth-code-123',
        client_id: 'client-123',
        client_secret: 'client-secret-123',
      };

      const result = OIDCTokenDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('grant_type');
      }
    });

    it('should accept authorization_code without code', () => {
      const validData = {
        grant_type: 'authorization_code' as const,
        client_id: 'client-123',
        client_secret: 'client-secret-123',
        redirect_uri: 'https://example.com/callback',
      };

      const result = OIDCTokenDto.safeParse(validData);
      expect(result.success).toBe(true);
    });

    it('should accept refresh_token without refresh_token', () => {
      const validData = {
        grant_type: 'refresh_token' as const,
        client_id: 'client-123',
        client_secret: 'client-secret-123',
      };

      const result = OIDCTokenDto.safeParse(validData);
      expect(result.success).toBe(true);
    });

    it('should reject empty client_id', () => {
      const invalidData = {
        grant_type: 'authorization_code' as const,
        code: 'auth-code-123',
        client_id: '',
        client_secret: 'client-secret-123',
      };

      const result = OIDCTokenDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('client_id');
      }
    });

    it('should reject empty client_secret', () => {
      const invalidData = {
        grant_type: 'authorization_code' as const,
        code: 'auth-code-123',
        client_id: 'client-123',
        client_secret: '',
      };

      const result = OIDCTokenDto.safeParse(invalidData);
      expect(result.success).toBe(false);
      if (!result.success) {
        expect(result.error.issues[0].path).toContain('client_secret');
      }
    });

    it('should accept token request without redirect_uri', () => {
      const validData = {
        grant_type: 'authorization_code' as const,
        code: 'auth-code-123',
        client_id: 'client-123',
        client_secret: 'client-secret-123',
      };

      const result = OIDCTokenDto.safeParse(validData);
      expect(result.success).toBe(true);
      if (result.success) {
        expect(result.data.redirect_uri).toBeUndefined();
      }
    });
  });
});