/**
 * Auto-Registration tests — zero-touch product provisioning.
 */

import { describe, it, expect, beforeEach } from 'vitest';
import { autoRegisterProduct, resetRateLimiter } from './auto-register.js';
import { loadProductCache, isValidProduct } from '../modules/products/cache.js';
import * as productRepo from '../modules/products/repository.js';

// Seed a known product so cache isn't empty
async function seedProduct(id: string): Promise<void> {
  await productRepo.create({
    id,
    productId: id,
    displayName: id.charAt(0).toUpperCase() + id.slice(1),
    licensePrefix: id.slice(0, 4).toUpperCase(),
    packageName: '',
    defaultPlan: 'free',
    trialDays: 14,
    deviceLimits: { free: 1, pro: 3, enterprise: 10 },
    websiteUrl: '',
    status: 'active',
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  });
  await loadProductCache();
}

describe('autoRegisterProduct', () => {
  beforeEach(async () => {
    resetRateLimiter();
    // Ensure cache is loaded (even if empty)
    await loadProductCache();
  });

  it('should auto-register an unknown productId', async () => {
    const result = await autoRegisterProduct('new-test-product', 'user-123');

    expect(result.registered).toBe(true);
    expect(result.product).toBeDefined();
    expect(result.product!.productId).toBe('new-test-product');
    expect(result.product!.status).toBe('active');
    expect(result.product!.displayName).toBe('New Test Product');
    expect(result.product!.defaultPlan).toBe('free');
    expect(result.product!.trialDays).toBe(14);

    // Cache should now include the new product
    expect(isValidProduct('new-test-product')).toBe(true);
  });

  it('should return already exists for a known product', async () => {
    await seedProduct('existing-prod');

    const result = await autoRegisterProduct('existing-prod', 'user-456');

    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Already exists');
    expect(result.product).toBeDefined();
  });

  it('should reject invalid productId format — uppercase', async () => {
    const result = await autoRegisterProduct('BadProduct', 'user-123');

    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Invalid productId format');
  });

  it('should reject invalid productId format — special characters', async () => {
    const result = await autoRegisterProduct('bad.product!', 'user-123');

    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Invalid productId format');
  });

  it('should reject empty productId', async () => {
    const result = await autoRegisterProduct('', 'user-123');

    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Invalid productId format');
  });

  it('should reject productId exceeding max length', async () => {
    const longId = 'a'.repeat(65);
    const result = await autoRegisterProduct(longId, 'user-123');

    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Invalid productId format');
  });

  it('should rate limit after max registrations', async () => {
    // Register 10 products (the max)
    for (let i = 0; i < 10; i++) {
      const result = await autoRegisterProduct(`rate-limit-test-${i}`, 'user-123');
      expect(result.registered).toBe(true);
    }

    // 11th should be rate limited
    const result = await autoRegisterProduct('rate-limit-test-overflow', 'user-123');
    expect(result.registered).toBe(false);
    expect(result.reason).toBe('Auto-registration rate limit exceeded');
  });

  it('should generate correct licensePrefix from productId', async () => {
    const result = await autoRegisterProduct('my-cool-app', 'user-123');

    expect(result.registered).toBe(true);
    expect(result.product!.licensePrefix).toBe('MYCOOLAP');
  });
});
