import { ReferralChainService } from '../../../src/domain/services/referral-chain.service';

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

  beforeEach(() => {
    service = new ReferralChainService();
  });

  describe('buildChain', () => {
    it('should build empty chain without referrer', () => {
      const chain = service.buildChain(null);
      expect(chain.chain).toEqual([]);
    });

    it('should build chain with referrer', () => {
      const chain = service.buildChain(100n, [200n, 300n]);
      expect(chain.chain).toEqual([100n, 200n, 300n]);
    });
  });

  describe('validateChain', () => {
    it('should return true for valid chain', () => {
      const chain = [100n, 200n, 300n];
      expect(service.validateChain(chain, 400n)).toBe(true);
    });

    it('should return false if user already in chain (circular)', () => {
      const chain = [100n, 200n, 300n];
      expect(service.validateChain(chain, 200n)).toBe(false);
    });

    it('should return false if chain exceeds max depth', () => {
      const chain = Array.from({ length: 10 }, (_, i) => BigInt(i + 1));
      expect(service.validateChain(chain, 100n)).toBe(false);
    });
  });

  describe('getAncestorsForUpdate', () => {
    it('should return all ancestors when no limit', () => {
      const chain = [100n, 200n, 300n];
      expect(service.getAncestorsForUpdate(chain)).toEqual([100n, 200n, 300n]);
    });

    it('should return limited ancestors when limit specified', () => {
      const chain = [100n, 200n, 300n, 400n, 500n];
      expect(service.getAncestorsForUpdate(chain, 3)).toEqual([100n, 200n, 300n]);
    });
  });

  describe('getLevelInChain', () => {
    it('should return correct level for ancestor', () => {
      const chain = [100n, 200n, 300n];
      expect(service.getLevelInChain(chain, 100n)).toBe(0);
      expect(service.getLevelInChain(chain, 200n)).toBe(1);
      expect(service.getLevelInChain(chain, 300n)).toBe(2);
    });

    it('should return -1 if ancestor not in chain', () => {
      const chain = [100n, 200n, 300n];
      expect(service.getLevelInChain(chain, 999n)).toBe(-1);
    });
  });
});
