// A1 Session 3 — partner ref capture: ?ref=CODE → first-party vyndr_ref
// cookie (90d, first-touch) → signup metadata partner_ref.

const fs = require('fs');
const path = require('path');
const {
  REF_COOKIE,
  sanitizeRefCode,
  parseRefFromSearch,
  readRefCookie,
  buildRefCookie,
  captureRef,
} = require('../../web/src/lib/partnerRef');

const WEB = path.join(__dirname, '..', '..', 'web', 'src');
const read = (rel) => fs.readFileSync(path.join(WEB, rel), 'utf8');

describe('sanitizeRefCode', () => {
  it('uppercases and accepts A-Z 0-9 - _', () => {
    expect(sanitizeRefCode('hoopspod')).toBe('HOOPSPOD');
    expect(sanitizeRefCode(' the-wire_22 ')).toBe('THE-WIRE_22');
  });
  it('rejects empty, too-long, and unsafe codes', () => {
    expect(sanitizeRefCode('')).toBeNull();
    expect(sanitizeRefCode(null)).toBeNull();
    expect(sanitizeRefCode('a'.repeat(33))).toBeNull();
    expect(sanitizeRefCode('bad code')).toBeNull();
    expect(sanitizeRefCode('<script>')).toBeNull();
    expect(sanitizeRefCode('a;b')).toBeNull();
  });
});

describe('parseRefFromSearch / readRefCookie / buildRefCookie', () => {
  it('parses ?ref= out of a search string', () => {
    expect(parseRefFromSearch('?ref=hoopspod&utm_source=x')).toBe('HOOPSPOD');
    expect(parseRefFromSearch('?utm_source=x')).toBeNull();
    expect(parseRefFromSearch('')).toBeNull();
  });
  it('builds a 90-day first-party cookie string', () => {
    const c = buildRefCookie('hoopspod');
    expect(c).toContain(`${REF_COOKIE}=HOOPSPOD`);
    expect(c).toContain(`Max-Age=${90 * 24 * 60 * 60}`);
    expect(c).toContain('Path=/');
    expect(c).toContain('SameSite=Lax');
    expect(c).not.toContain('Secure');
    expect(buildRefCookie('hoopspod', { secure: true })).toContain('; Secure');
    expect(buildRefCookie('bad code')).toBeNull();
  });
  it('reads the cookie back out of a document.cookie string', () => {
    expect(readRefCookie('foo=1; vyndr_ref=HOOPSPOD; bar=2')).toBe('HOOPSPOD');
    expect(readRefCookie('foo=1; bar=2')).toBeNull();
    expect(readRefCookie('')).toBeNull();
  });
});

describe('captureRef — first touch wins', () => {
  const fakeWindow = (search, cookie = '') => {
    const doc = { cookie };
    return { location: { search, protocol: 'https:' }, document: doc };
  };

  it('sets the cookie on a first visit with ?ref=', () => {
    const w = fakeWindow('?ref=hoopspod');
    expect(captureRef(w)).toBe('HOOPSPOD');
    expect(w.document.cookie).toContain('vyndr_ref=HOOPSPOD');
    expect(w.document.cookie).toContain('; Secure'); // https origin
  });

  it('does NOT overwrite an existing ref cookie (first touch)', () => {
    const w = fakeWindow('?ref=newpartner', 'vyndr_ref=ORIGINAL');
    expect(captureRef(w)).toBeNull();
    expect(w.document.cookie).toBe('vyndr_ref=ORIGINAL');
  });

  it('no-ops without a ref param or without a window', () => {
    const w = fakeWindow('?utm_source=x');
    expect(captureRef(w)).toBeNull();
    expect(w.document.cookie).toBe('');
    expect(captureRef(null)).toBeNull();
  });
});

describe('wiring (source-asserted)', () => {
  it('PartnerRefCapture is mounted in the layout (GlobalHosts pattern)', () => {
    const layout = read('app/layout.tsx');
    expect(layout).toContain('<PartnerRefCapture />');
    expect(layout).toContain("from '@/components/vyndr/PartnerRefCapture'");
  });
  it('signUp forwards the cookie as partner_ref signup metadata', () => {
    const auth = read('contexts/AuthContext.tsx');
    expect(auth).toContain('readRefCookie(document.cookie)');
    expect(auth).toContain('partner_ref: partnerRef');
  });
});
