/**
 * Jest tests for schema validation with snapshots
 */

import { 
  StarredProjectsResponseSchema,
  DeepLinkParamsSchema,
  ErrorResponseSchema,
  RateLimitResponseSchema,
  AcknowledgmentRequestSchema,
  AcknowledgmentResponseSchema,
  ClockSyncResponseSchema
} from '../schemas';

describe('Schema Validation', () => {
  describe('StarredProjectsResponseSchema', () => {
    it('should validate canonical response envelope', () => {
      const canonicalResponse = {
        data: [
          {
            planSummary: {
              jwtId: '1704067200_abc123_def45678',
              handleId: 'test_project_1',
              name: 'Test Project 1',
              description: 'First test project',
              issuerDid: 'did:key:test_issuer_1',
              agentDid: 'did:key:test_agent_1',
              startTime: '2025-01-01T00:00:00Z',
              endTime: '2025-01-31T23:59:59Z',
              locLat: 40.7128,
              locLon: -74.0060,
              url: 'https://project-url.com',
              version: '1.0.0'
            },
            previousClaim: {
              jwtId: '1703980800_xyz789_12345678',
              claimType: 'project_update',
              claimData: {
                status: 'in_progress',
                progress: 0.75
              },
              metadata: {
                createdAt: '2025-01-01T10:00:00Z',
                updatedAt: '2025-01-01T12:00:00Z'
              }
            }
          }
        ],
        hitLimit: false,
        pagination: {
          hasMore: false,
          nextAfterId: null
        }
      };

      const result = StarredProjectsResponseSchema.safeParse(canonicalResponse);
      if (!result.success) {
        // Schema validation errors logged for debugging
      }
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('canonical-response-envelope');
    });

    it('should validate empty response', () => {
      const emptyResponse = {
        data: [],
        hitLimit: false,
        pagination: {
          hasMore: false,
          nextAfterId: null
        }
      };

      const result = StarredProjectsResponseSchema.safeParse(emptyResponse);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('empty-response');
    });

    it('should validate paginated response', () => {
      const paginatedResponse = {
        data: [], // Would contain 100 items in real scenario
        hitLimit: true,
        pagination: {
          hasMore: true,
          nextAfterId: '1704153600_mno345_87654321'
        }
      };

      const result = StarredProjectsResponseSchema.safeParse(paginatedResponse);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('paginated-response');
    });
  });

  describe('DeepLinkParamsSchema', () => {
    it('should validate single JWT ID params', () => {
      const params = {
        jwtId: '1704067200_abc123_def45678'
      };

      const result = DeepLinkParamsSchema.safeParse(params);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('single-jwt-id-params');
    });

    it('should validate multiple JWT IDs params', () => {
      const params = {
        jwtIds: [
          '1704067200_abc123_12345678',
          '1704153600_mno345_87654321',
          '1704240000_new123_abcdef01'
        ]
      };

      const result = DeepLinkParamsSchema.safeParse(params);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('multiple-jwt-ids-params');
    });

    it('should validate project ID params', () => {
      const params = {
        projectId: 'test_project_123'
      };

      const result = DeepLinkParamsSchema.safeParse(params);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('project-id-params');
    });

    it('should validate shortlink params', () => {
      const params = {
        shortlink: 'abc123def456789'
      };

      const result = DeepLinkParamsSchema.safeParse(params);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('shortlink-params');
    });

    it('should reject invalid params', () => {
      const invalidParams = {
        jwtIds: ['invalid_jwt_id'],
        projectId: 'invalid@project#id'
      };

      const result = DeepLinkParamsSchema.safeParse(invalidParams);
      expect(result.success).toBe(false);
      expect(result.success ? null : result.error).toMatchSnapshot('invalid-params-error');
    });
  });

  describe('ErrorResponseSchema', () => {
    it('should validate rate limit error', () => {
      const rateLimitError = {
        error: 'Rate limit exceeded',
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Rate limit exceeded for DID',
        details: {
          limit: 100,
          window: '1m',
          resetAt: '2025-01-01T12:01:00Z'
        },
        retryAfter: 60,
        requestId: 'req_jkl012'
      };

      const result = RateLimitResponseSchema.safeParse(rateLimitError);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('rate-limit-error');
    });

    it('should validate generic error', () => {
      const genericError = {
        error: 'internal_server_error',
        message: 'Database connection timeout',
        details: {
          component: 'database',
          operation: 'query_starred_projects'
        },
        requestId: 'req_mno345'
      };

      const result = ErrorResponseSchema.safeParse(genericError);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('generic-error');
    });
  });

  describe('AcknowledgmentRequestSchema', () => {
    it('should validate acknowledgment request', () => {
      const ackRequest = {
        acknowledgedJwtIds: [
          '1704067200_abc123_12345678',
          '1704153600_mno345_87654321'
        ],
        acknowledgedAt: '2025-01-01T12:00:00Z',
        clientVersion: 'TimeSafari-DailyNotificationPlugin/1.0.0'
      };

      const result = AcknowledgmentRequestSchema.safeParse(ackRequest);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('acknowledgment-request');
    });
  });

  describe('AcknowledgmentResponseSchema', () => {
    it('should validate acknowledgment response', () => {
      const ackResponse = {
        acknowledged: 2,
        failed: 0,
        alreadyAcknowledged: 0,
        acknowledgmentId: 'ack_xyz789',
        timestamp: '2025-01-01T12:00:00Z'
      };

      const result = AcknowledgmentResponseSchema.safeParse(ackResponse);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('acknowledgment-response');
    });
  });

  describe('ClockSyncResponseSchema', () => {
    it('should validate clock sync response', () => {
      const clockSyncResponse = {
        serverTime: 1704067200000,
        clientTime: 1704067195000,
        offset: 5000,
        ntpServers: ['pool.ntp.org', 'time.google.com']
      };

      const result = ClockSyncResponseSchema.safeParse(clockSyncResponse);
      expect(result.success).toBe(true);
      expect(result.success ? result.data : null).toMatchSnapshot('clock-sync-response');
    });
  });
});
