import { describe, it, expect } from 'vitest';
import { CreateIPRuleSchema } from './types.js';
import type { IPRuleDoc, IPAction, RateLimitStats } from './types.js';

describe('CreateIPRuleSchema', () => {
  it('accepts valid deny rule', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '192.168.1.100',
      action: 'deny',
      reason: 'Brute force attempt',
    });
    expect(result.success).toBe(true);
  });

  it('accepts valid allow rule', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '10.0.0.0/8',
      action: 'allow',
      reason: 'Internal network',
    });
    expect(result.success).toBe(true);
  });

  it('accepts rule with expiry', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '203.0.113.50',
      action: 'deny',
      reason: 'Temporary block',
      expiresAt: '2026-03-20T00:00:00.000Z',
    });
    expect(result.success).toBe(true);
  });

  it('rejects empty IP', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '',
      action: 'deny',
      reason: 'Test',
    });
    expect(result.success).toBe(false);
  });

  it('rejects invalid action', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '1.2.3.4',
      action: 'block',
      reason: 'Test',
    });
    expect(result.success).toBe(false);
  });

  it('rejects empty reason', () => {
    const result = CreateIPRuleSchema.safeParse({
      ip: '1.2.3.4',
      action: 'deny',
      reason: '',
    });
    expect(result.success).toBe(false);
  });

  it('accepts both valid actions', () => {
    const actions: IPAction[] = ['allow', 'deny'];
    for (const action of actions) {
      const result = CreateIPRuleSchema.safeParse({ ip: '1.2.3.4', action, reason: 'Test' });
      expect(result.success).toBe(true);
    }
  });
});

describe('IPRuleDoc type coverage', () => {
  it('should allow building a valid IP rule', () => {
    const doc: IPRuleDoc = {
      id: 'ipr_123',
      productId: 'lysnrai',
      ip: '192.168.1.0/24',
      action: 'deny',
      reason: 'Suspicious traffic from this subnet',
      createdBy: 'usr_admin',
      createdAt: new Date().toISOString(),
    };
    expect(doc.action).toBe('deny');
    expect(doc.expiresAt).toBeUndefined();
  });

  it('should allow temporary rule with expiry', () => {
    const doc: IPRuleDoc = {
      id: 'ipr_456',
      productId: 'lysnrai',
      ip: '203.0.113.50',
      action: 'deny',
      reason: '24h block after abuse',
      createdBy: 'usr_admin',
      createdAt: new Date().toISOString(),
      expiresAt: new Date(Date.now() + 86400000).toISOString(),
    };
    expect(doc.expiresAt).toBeDefined();
  });
});

describe('RateLimitStats type coverage', () => {
  it('should allow building stats object', () => {
    const stats: RateLimitStats = {
      total429s: 42,
      topKeys: [
        { key: '192.168.1.100', count: 15, lastAt: new Date().toISOString() },
        { key: 'usr_abc', count: 12, lastAt: new Date().toISOString() },
      ],
      windowStart: new Date(Date.now() - 3600000).toISOString(),
    };
    expect(stats.total429s).toBe(42);
    expect(stats.topKeys).toHaveLength(2);
  });
});
