import { describe, it, expect } from 'vitest';
import { phishingDetector } from '../src/lib/phishing-detector';
import { UrlVerdict, ThreatType } from '../src/types';

describe('PhishingDetector', () => {
  const detector = phishingDetector;

  describe('analyzeUrl', () => {
    it('should return SAFE for legitimate URLs', () => {
      const result = detector.analyzeUrl('https://www.google.com/search?q=test');
      expect(result.verdict).toBe(UrlVerdict.SAFE);
      expect(result.score).toBeLessThan(20);
    });

    it('should detect suspicious TLD', () => {
      const result = detector.analyzeUrl('https://free-prize.tk/claim');
      expect(result.threats.some((t) => t.type === ThreatType.DOMAIN_AGE)).toBe(true);
      expect(result.score).toBeGreaterThanOrEqual(25);
    });

    it('should detect typosquatting', () => {
      const result = detector.analyzeUrl('https://goggle.com/login');
      expect(result.threats.some((t) => t.type === ThreatType.TYPOSQUAT)).toBe(true);
      expect(result.score).toBeGreaterThanOrEqual(35);
    });

    it('should detect IP address hostname', () => {
      const result = detector.analyzeUrl('http://192.168.1.100/admin');
      expect(result.threats.some((t) => t.type === ThreatType.PHISHING_HEURISTIC)).toBe(true);
      expect(result.score).toBeGreaterThanOrEqual(25);
    });

    it('should detect phishing pattern in hostname', () => {
      const result = detector.analyzeUrl('https://login-secure-portal.xyz/account');
      expect(result.threats.some((t) => t.type === ThreatType.PHISHING_HEURISTIC)).toBe(true);
    });

    it('should detect HTTP protocol', () => {
      const result = detector.analyzeUrl('http://example.com/login');
      expect(result.threats.some((t) => t.type === ThreatType.MIXED_CONTENT)).toBe(true);
    });

    it('should detect deep subdomain nesting', () => {
      const result = detector.analyzeUrl('https://a.b.c.d.e.f.example.com/login');
      expect(result.threats.some((t) => t.type === ThreatType.PHISHING_HEURISTIC)).toBe(true);
    });

    it('should detect multiple redirect parameters', () => {
      const result = detector.analyzeUrl('https://example.com/page?redirect=/login&next=/dashboard&return=/home');
      expect(result.threats.some((t) => t.type === ThreatType.REDIRECT_CHAIN)).toBe(true);
    });

    it('should detect excessive URL encoding', () => {
      const result = detector.analyzeUrl('https://example.com/%3f%3d%26%23%40%24%5e');
      expect(result.threats.some((t) => t.type === ThreatType.URL_ENTROPY)).toBe(true);
    });

    it('should detect high URL path entropy', () => {
      const result = detector.analyzeUrl('https://example.com/a8f3k2m9x7q1w4e6r5t0y2u8i3o7p');
      expect(result.threats.some((t) => t.type === ThreatType.URL_ENTROPY)).toBe(true);
    });

    it('should return SUSPICIOUS for moderate score', () => {
      const result = detector.analyzeUrl('http://goggle.com/login-secure');
      expect(result.verdict).toBe(UrlVerdict.SUSPICIOUS);
    });

    it('should return PHISHING for high score', () => {
      const result = detector.analyzeUrl('http://goggle.tk/login-secure-portal?redirect=/a&next=/b');
      expect(result.verdict).toBe(UrlVerdict.PHISHING);
    });

    it('should handle malformed URLs', () => {
      const result = detector.analyzeUrl('not-a-real-url');
      expect(result.verdict).toBe(UrlVerdict.UNKNOWN);
    });

    it('should detect brand impersonation patterns', () => {
      const result = detector.analyzeUrl('https://account-verify-now.com/paypal');
      expect(result.threats.some((t) => t.type === ThreatType.PHISHING_HEURISTIC)).toBe(true);
    });
  });

  describe('verdict thresholds', () => {
    it('should classify score < 20 as SAFE', () => {
      const result = detector.analyzeUrl('https://www.microsoft.com');
      expect(result.verdict).toBe(UrlVerdict.SAFE);
    });

    it('should classify score >= 20 as SPAM', () => {
      const result = detector.analyzeUrl('https://example.tk/page');
      if (result.score >= 20 && result.score < 40) {
        expect(result.verdict).toBe(UrlVerdict.SPAM);
      }
    });

    it('should classify score >= 40 as SUSPICIOUS', () => {
      const result = detector.analyzeUrl('http://g00gle.tk/login');
      if (result.score >= 40 && result.score < 70) {
        expect(result.verdict).toBe(UrlVerdict.SUSPICIOUS);
      }
    });

    it('should classify score >= 70 as PHISHING', () => {
      const result = detector.analyzeUrl('http://g00gle.tk/login-secure-portal?redirect=/a&next=/b');
      if (result.score >= 70) {
        expect(result.verdict).toBe(UrlVerdict.PHISHING);
      }
    });
  });
});
