import { Test } from '@nestjs/testing';
import { describe, it, expect, beforeEach } from 'vitest';

import { AttributionService } from './attribution.service';

describe('AttributionService', () => {
  let service: AttributionService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [AttributionService],
    }).compile();

    service = module.get<AttributionService>(AttributionService);
  });

  describe('resolveTrafficSource', () => {
    it('returns direct traffic when no attribution data', () => {
      const result = service.resolveTrafficSource({});

      expect(result.source).toBe('direct');
      expect(result.rawSource).toBeNull();
      expect(result.medium).toBeNull();
      expect(result.campaign).toBeNull();
      expect(result.referrer).toBeNull();
    });

    it('preserves all UTM parameters in result', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'cpc',
        utmCampaign: 'winter-sale',
        utmContent: 'ad-variant-a',
        utmTerm: 'luxury+watches',
      });

      expect(result.rawSource).toBe('google');
      expect(result.medium).toBe('cpc');
      expect(result.campaign).toBe('winter-sale');
      expect(result.content).toBe('ad-variant-a');
      expect(result.term).toBe('luxury+watches');
    });
  });

  describe('UTM parameter resolution', () => {
    it('classifies paid search from utm_medium=cpc', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'cpc',
      });

      expect(result.source).toBe('paid');
    });

    it('classifies paid search from utm_medium=ppc', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'ppc',
      });

      expect(result.source).toBe('paid');
    });

    it('classifies paid search from utm_medium=paid', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'paid',
      });

      expect(result.source).toBe('paid');
    });

    it('classifies paid search from utm_medium=paidsearch', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'paidsearch',
      });

      expect(result.source).toBe('paid');
    });

    it('classifies email from utm_medium=email', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'mailchimp',
        utmMedium: 'email',
      });

      expect(result.source).toBe('email');
    });

    it('classifies email from utm_medium=newsletter', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'campaign-monitor',
        utmMedium: 'newsletter',
      });

      expect(result.source).toBe('email');
    });

    it('classifies social from utm_medium=social', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'facebook',
        utmMedium: 'social',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from utm_medium=social-media', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'twitter',
        utmMedium: 'social-media',
      });

      expect(result.source).toBe('social');
    });

    it('classifies affiliate from utm_medium=affiliate', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'partner123',
        utmMedium: 'affiliate',
      });

      expect(result.source).toBe('affiliate');
    });

    it('classifies affiliate from utm_medium=partner', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'partner456',
        utmMedium: 'partner',
      });

      expect(result.source).toBe('affiliate');
    });

    it('classifies organic from utm_medium=organic', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'organic',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies referral from utm_medium=referral', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'blog.example.com',
        utmMedium: 'referral',
      });

      expect(result.source).toBe('referral');
    });
  });

  describe('UTM source-based classification', () => {
    it('classifies social from social platform utm_source', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'facebook',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from twitter', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'twitter',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from instagram', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'instagram',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from linkedin', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'linkedin',
      });

      expect(result.source).toBe('social');
    });

    it('classifies organic from search engine with no medium', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies paid from search engine with cpc medium', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'cpc',
      });

      expect(result.source).toBe('paid');
    });

    it('classifies referral from unknown utm_source', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'blog.example.com',
      });

      expect(result.source).toBe('referral');
    });
  });

  describe('referrer analysis', () => {
    it('classifies social from facebook referrer', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.facebook.com/some-post',
      });

      expect(result.source).toBe('social');
      expect(result.referrer).toBe('https://www.facebook.com/some-post');
    });

    it('classifies social from twitter referrer', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://t.co/abc123',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from x.com', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://x.com/user/status/123',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from instagram', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.instagram.com/p/abc123/',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from linkedin', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.linkedin.com/feed/',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from reddit', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.reddit.com/r/programming/',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from youtube', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.youtube.com/watch?v=abc123',
      });

      expect(result.source).toBe('social');
    });

    it('classifies social from tiktok', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.tiktok.com/@user/video/123',
      });

      expect(result.source).toBe('social');
    });

    it('classifies organic from google search', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.google.com/search?q=test',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies organic from bing', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.bing.com/search?q=test',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies organic from duckduckgo', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://duckduckgo.com/?q=test',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies organic from yahoo', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://search.yahoo.com/search?p=test',
      });

      expect(result.source).toBe('organic');
    });

    it('classifies referral from unknown domain', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://blog.example.com/article',
      });

      expect(result.source).toBe('referral');
    });

    it('handles referrer without www prefix', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://facebook.com/page',
      });

      expect(result.source).toBe('social');
    });

    it('handles invalid referrer URL gracefully', () => {
      const result = service.resolveTrafficSource({
        referrer: 'not-a-valid-url',
      });

      expect(result.source).toBe('direct');
    });
  });

  describe('priority resolution', () => {
    it('prioritizes UTM parameters over referrer', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'newsletter',
        utmMedium: 'email',
        referrer: 'https://www.facebook.com/',
      });

      expect(result.source).toBe('email');
    });

    it('uses referrer when UTM parameters are missing', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://www.google.com/search',
      });

      expect(result.source).toBe('organic');
    });

    it('returns direct when both UTM and referrer are missing', () => {
      const result = service.resolveTrafficSource({});

      expect(result.source).toBe('direct');
    });
  });

  describe('edge cases', () => {
    it('handles empty string UTM parameters', () => {
      const result = service.resolveTrafficSource({
        utmSource: '',
        utmMedium: '',
        referrer: '',
      });

      expect(result.source).toBe('direct');
    });

    it('handles case-insensitive UTM medium', () => {
      const result1 = service.resolveTrafficSource({ utmMedium: 'CPC' });
      const result2 = service.resolveTrafficSource({ utmMedium: 'Cpc' });
      const result3 = service.resolveTrafficSource({ utmMedium: 'cpc' });

      expect(result1.source).toBe('paid');
      expect(result2.source).toBe('paid');
      expect(result3.source).toBe('paid');
    });

    it('handles case-insensitive UTM source', () => {
      const result1 = service.resolveTrafficSource({ utmSource: 'FACEBOOK' });
      const result2 = service.resolveTrafficSource({ utmSource: 'Facebook' });
      const result3 = service.resolveTrafficSource({ utmSource: 'facebook' });

      expect(result1.source).toBe('social');
      expect(result2.source).toBe('social');
      expect(result3.source).toBe('social');
    });

    it('handles subdomains in referrer', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://subdomain.facebook.com/page',
      });

      expect(result.source).toBe('social');
    });

    it('handles country-specific Google domains', () => {
      const resultUK = service.resolveTrafficSource({
        referrer: 'https://www.google.co.uk/search',
      });
      const resultDE = service.resolveTrafficSource({
        referrer: 'https://www.google.de/search',
      });

      expect(resultUK.source).toBe('organic');
      expect(resultDE.source).toBe('organic');
    });

    it('handles Yandex with subdomain', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://yandex.ru/search',
      });

      expect(result.source).toBe('organic');
    });
  });

  describe('complex scenarios', () => {
    it('handles paid social campaign', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'facebook',
        utmMedium: 'cpc',
        utmCampaign: 'summer-promo',
        utmContent: 'ad-creative-1',
      });

      expect(result.source).toBe('paid');
      expect(result.rawSource).toBe('facebook');
      expect(result.medium).toBe('cpc');
      expect(result.campaign).toBe('summer-promo');
      expect(result.content).toBe('ad-creative-1');
    });

    it('handles organic social without UTM', () => {
      const result = service.resolveTrafficSource({
        referrer: 'https://twitter.com/user/status/123',
      });

      expect(result.source).toBe('social');
      expect(result.rawSource).toBeNull();
      expect(result.medium).toBeNull();
    });

    it('handles email campaign with full UTM', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'mailchimp',
        utmMedium: 'email',
        utmCampaign: 'weekly-digest',
        utmContent: 'header-cta',
      });

      expect(result.source).toBe('email');
      expect(result.rawSource).toBe('mailchimp');
      expect(result.medium).toBe('email');
      expect(result.campaign).toBe('weekly-digest');
      expect(result.content).toBe('header-cta');
    });

    it('handles affiliate partnership', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'partner-site',
        utmMedium: 'affiliate',
        utmCampaign: 'q1-partnership',
      });

      expect(result.source).toBe('affiliate');
      expect(result.rawSource).toBe('partner-site');
    });

    it('handles branded search campaign', () => {
      const result = service.resolveTrafficSource({
        utmSource: 'google',
        utmMedium: 'cpc',
        utmCampaign: 'brand-protection',
        utmTerm: 'company+name',
      });

      expect(result.source).toBe('paid');
      expect(result.term).toBe('company+name');
    });
  });
});
