const fs = require('fs');
const path = require('path');

const sql = fs.readFileSync(
  path.join(__dirname, '../../supabase/migrations/004_affiliate_tables.sql'),
  'utf8'
);

describe('Migration 004 — Affiliate Tables', () => {
  test('creates referral_codes table', () => {
    expect(sql).toContain('CREATE TABLE IF NOT EXISTS referral_codes');
  });

  test('creates wallet_addresses table', () => {
    expect(sql).toContain('CREATE TABLE IF NOT EXISTS wallet_addresses');
  });

  test('creates referral_conversions table', () => {
    expect(sql).toContain('CREATE TABLE IF NOT EXISTS referral_conversions');
  });

  test('creates affiliate_payouts table', () => {
    expect(sql).toContain('CREATE TABLE IF NOT EXISTS affiliate_payouts');
  });

  test('referral_codes has unique code constraint', () => {
    expect(sql).toMatch(/code TEXT NOT NULL UNIQUE/);
  });

  test('referral_codes has affiliate_tier constraint', () => {
    expect(sql).toMatch(/affiliate_tier.*CHECK.*\(affiliate_tier IN/);
  });

  test('referral_conversions has conversion_type constraint', () => {
    expect(sql).toMatch(/conversion_type.*CHECK.*\(conversion_type IN.*'signup'.*'upgrade'.*'renewal'/);
  });

  test('referral_conversions has status constraint', () => {
    expect(sql).toMatch(/status.*CHECK.*\(status IN.*'pending'.*'confirmed'.*'paid'/);
  });

  test('affiliate_payouts has payout_method constraint', () => {
    expect(sql).toMatch(/payout_method.*CHECK.*\(payout_method IN.*'crypto'.*'paypal'/);
  });

  test('wallet_addresses has chain constraint', () => {
    expect(sql).toMatch(/chain.*CHECK.*\(chain IN.*'ethereum'.*'solana'/);
  });

  test('RLS enabled on all four tables', () => {
    expect(sql).toContain('ALTER TABLE referral_codes ENABLE ROW LEVEL SECURITY');
    expect(sql).toContain('ALTER TABLE referral_conversions ENABLE ROW LEVEL SECURITY');
    expect(sql).toContain('ALTER TABLE affiliate_payouts ENABLE ROW LEVEL SECURITY');
    expect(sql).toContain('ALTER TABLE wallet_addresses ENABLE ROW LEVEL SECURITY');
  });

  test('referral_codes has public read policy', () => {
    expect(sql).toContain('referral_codes_public_read');
    expect(sql).toContain('FOR SELECT USING (true)');
  });

  test('service role has full access on all tables', () => {
    expect(sql).toContain('referral_codes_service_write');
    expect(sql).toContain('referral_conversions_service_access');
    expect(sql).toContain('affiliate_payouts_service_access');
    expect(sql).toContain('wallet_addresses_service_access');
  });

  test('wallet_addresses is created before affiliate_payouts (FK dependency)', () => {
    const walletPos = sql.indexOf('CREATE TABLE IF NOT EXISTS wallet_addresses');
    const payoutsPos = sql.indexOf('CREATE TABLE IF NOT EXISTS affiliate_payouts');
    expect(walletPos).toBeLessThan(payoutsPos);
  });

  test('affiliate_payouts references wallet_addresses', () => {
    expect(sql).toMatch(/wallet_address_id UUID REFERENCES wallet_addresses\(id\)/);
  });

  test('indexes created for key lookup columns', () => {
    expect(sql).toContain('idx_referral_codes_owner');
    expect(sql).toContain('idx_referral_codes_code');
    expect(sql).toContain('idx_referral_conversions_code');
    expect(sql).toContain('idx_affiliate_payouts_user');
    expect(sql).toContain('idx_wallet_addresses_user');
  });
});
