import assert from 'assert';
import { db } from '@/db/client';
import { REALISTIC_DEMO_STORES } from '@/lib/saas-admin/demoData';
import {
  signAdminToken,
  verifyAdminToken,
  hashPassword,
  verifyPassword,
  checkAdminPermission,
} from '@/lib/auth/adminAuth';

async function runSaasAdminVerification() {
  console.log('\n======================================================');
  console.log('🧪 RUNNING SAAS ADMIN & MULTI-STORE VERIFICATION SUITE');
  console.log('======================================================\n');

  let passed = 0;
  let total = 0;

  function test(name: string, fn: () => void | Promise<void>) {
    total++;
    try {
      const res = fn();
      if (res instanceof Promise) {
        return res
          .then(() => {
            console.log(`  ✓ ${name}`);
            passed++;
          })
          .catch((err) => {
            console.error(`  ✕ ${name}: ${err.message}`);
          });
      }
      console.log(`  ✓ ${name}`);
      passed++;
    } catch (err: any) {
      console.error(`  ✕ ${name}: ${err.message}`);
    }
  }

  // --------------------------------------------------------------------------
  console.log('📦 1. Admin Authentication & Role-Based Access Control (RBAC):');
  // --------------------------------------------------------------------------

  await test('Password hashing and PBKDF2 verification', () => {
    const { hash, salt } = hashPassword('secure_admin_pass_2026');
    assert.ok(hash && salt, 'Hash and salt should be generated');
    assert.strictEqual(verifyPassword('secure_admin_pass_2026', hash, salt), true, 'Correct password passes');
    assert.strictEqual(verifyPassword('wrong_password', hash, salt), false, 'Wrong password rejected');
  });

  await test('Admin token signing and HMAC-SHA256 verification', () => {
    const admin = {
      id: 'admin_test_1',
      email: 'admin@meta-connector.app',
      name: 'Sarah Jenkins',
      role: 'super_admin' as const,
    };
    const token = signAdminToken(admin);
    assert.ok(token.includes('.'), 'Token should have JWT structure');

    const verified = verifyAdminToken(token);
    assert.strictEqual(verified.valid, true, 'Valid token accepted');
    assert.strictEqual(verified.payload?.sub, 'admin_test_1');
    assert.strictEqual(verified.payload?.role, 'super_admin');
  });

  await test('Forged or tampered admin token is rejected', () => {
    const admin = {
      id: 'admin_test_2',
      email: 'hacker@example.com',
      name: 'Hacker',
      role: 'support_agent' as const,
    };
    const token = signAdminToken(admin);
    const tampered = token.slice(0, -6) + 'abcdef';
    const result = verifyAdminToken(tampered);
    assert.strictEqual(result.valid, false, 'Tampered token rejected');
  });

  await test('Role-based permission boundaries (Super Admin vs Support Agent)', () => {
    assert.strictEqual(checkAdminPermission('super_admin', 'manage_stores'), true);
    assert.strictEqual(checkAdminPermission('super_admin', 'manage_billing'), true);
    assert.strictEqual(checkAdminPermission('super_admin', 'manage_admins'), true);

    assert.strictEqual(checkAdminPermission('billing_admin', 'manage_billing'), true);
    assert.strictEqual(checkAdminPermission('billing_admin', 'manage_stores'), false);
    assert.strictEqual(checkAdminPermission('billing_admin', 'manage_admins'), false);

    assert.strictEqual(checkAdminPermission('support_agent', 'view_only'), true);
    assert.strictEqual(checkAdminPermission('support_agent', 'manage_billing'), false);
    assert.strictEqual(checkAdminPermission('support_agent', 'manage_stores'), false);
  });

const TEST_FIXTURE_STORES = [
  {
    id: 'shop_aurora_apparel',
    shopify_domain: 'aurora-apparel-official.myshopify.com',
    shopify_shop_id: 'gid://shopify/Shop/98234101',
    shop_name: 'Aurora Apparel & Co.',
    owner_email: 'charlotte@auroraapparel.com',
    country: 'United States',
    country_code: 'US',
    status: 'installed' as const,
    plan: 'accelerate' as const,
    plan_name: 'Accelerate Plan',
    plan_price: 99,
    subscription_status: 'active' as const,
    monthly_revenue: 99,
    stats: { productsCount: 100, pixelsCount: 1, eventsCount: 50 },
    billingHistory: [{ id: 'b1', amount: 99 }],
    activityHistory: [{ id: 'a1', action: 'installed' }],
  },
  {
    id: 'shop_tokyo_streetwear',
    shopify_domain: 'tokyo-drift-harajuku.myshopify.com',
    shopify_shop_id: 'gid://shopify/Shop/98234104',
    shop_name: 'Tokyo Drift Harajuku',
    owner_email: 'kenji@tokyodrift.jp',
    country: 'Japan',
    country_code: 'JP',
    status: 'installed' as const,
    plan: 'basic' as const,
    plan_name: 'Basic Plan',
    plan_price: 0,
    subscription_status: 'free' as const,
    monthly_revenue: 0,
    stats: { productsCount: 50, pixelsCount: 1, eventsCount: 10 },
    billingHistory: [],
    activityHistory: [{ id: 'a2', action: 'installed' }],
  },
  {
    id: 'shop_trial_store',
    shopify_domain: 'trial-store.myshopify.com',
    shopify_shop_id: 'gid://shopify/Shop/98234105',
    shop_name: 'Trial Fitness Co',
    owner_email: 'owner@trialfitness.com',
    country: 'United States',
    country_code: 'US',
    status: 'installed' as const,
    plan: 'growth' as const,
    plan_name: 'Growth Plan',
    plan_price: 13,
    subscription_status: 'trial' as const,
    monthly_revenue: 0,
    stats: { productsCount: 20, pixelsCount: 1, eventsCount: 0 },
    billingHistory: [],
    activityHistory: [{ id: 'a3', action: 'installed' }],
  },
  {
    id: 'shop_churned_store',
    shopify_domain: 'churned-store.myshopify.com',
    shopify_shop_id: 'gid://shopify/Shop/98234106',
    shop_name: 'Old Store',
    owner_email: 'owner@oldstore.com',
    country: 'United States',
    country_code: 'US',
    status: 'uninstalled' as const,
    uninstalled_at: '2026-10-01T00:00:00Z',
    plan: 'growth' as const,
    plan_name: 'Growth Plan',
    plan_price: 13,
    subscription_status: 'cancelled' as const,
    monthly_revenue: 0,
    stats: { productsCount: 0, pixelsCount: 0, eventsCount: 0 },
    billingHistory: [],
    activityHistory: [{ id: 'a4', action: 'uninstalled' }],
  },
];

  // --------------------------------------------------------------------------
  console.log('\n📦 2. Strict Business Logic & Revenue Metrics Verification:');
  // --------------------------------------------------------------------------

  await test('Free users must never be counted as paid subscribers', () => {
    const freeStore = TEST_FIXTURE_STORES.find((s) => s.plan === 'basic' || s.plan_price === 0);
    assert.ok(freeStore, 'Test fixtures must have at least one free store');
    assert.strictEqual(freeStore.plan_price, 0);
    assert.strictEqual(freeStore.monthly_revenue, 0);
    assert.notStrictEqual(freeStore.subscription_status, 'active');
  });

  await test('MRR calculation strictly includes only verified active paid plans', () => {
    const activePaid = TEST_FIXTURE_STORES.filter(
      (s) => s.status === 'installed' && s.subscription_status === 'active' && s.plan_price > 0
    );
    const calculatedMRR = activePaid.reduce((sum, s) => sum + s.plan_price, 0);
    assert.ok(calculatedMRR > 0, 'MRR should be greater than zero for active paid stores');

    // Make sure trial stores ($0 revenue during trial) are excluded from MRR
    const trialStores = TEST_FIXTURE_STORES.filter((s) => s.subscription_status === 'trial');
    for (const ts of trialStores) {
      assert.strictEqual(ts.monthly_revenue, 0, 'Trial stores must have $0 current monthly revenue');
    }
  });

  await test('Uninstalled stores retain uninstalled status and zero revenue (no duplicate records)', () => {
    const uninstalled = TEST_FIXTURE_STORES.filter((s) => s.status === 'uninstalled');
    assert.ok(uninstalled.length > 0, 'Should have uninstalled stores for churn reporting');
    for (const u of uninstalled) {
      assert.strictEqual(u.monthly_revenue, 0, 'Uninstalled stores generate 0 revenue');
      assert.ok(u.uninstalled_at, 'Uninstalled stores must have uninstalled_at timestamp');
    }
  });

  // --------------------------------------------------------------------------
  console.log('\n📦 3. Multi-Store Search, Filtering & CSV Export:');
  // --------------------------------------------------------------------------

  await test('Store search matches name, domain, and email', () => {
    const query = 'aurora';
    const matches = TEST_FIXTURE_STORES.filter(
      (s) =>
        s.shop_name.toLowerCase().includes(query) ||
        s.shopify_domain.toLowerCase().includes(query) ||
        s.owner_email.toLowerCase().includes(query)
    );
    assert.ok(matches.length >= 1, 'Should match Aurora store');
    assert.strictEqual(matches[0].id, 'shop_aurora_apparel');
  });

  await test('Country filtering returns stores accurately', () => {
    const usStores = TEST_FIXTURE_STORES.filter((s) => s.country_code === 'US');
    const jpStores = TEST_FIXTURE_STORES.filter((s) => s.country_code === 'JP');
    assert.ok(usStores.length >= 2, 'Should have US stores');
    assert.ok(jpStores.length >= 1, 'Should have Japanese stores');
    assert.strictEqual(jpStores[0].id, 'shop_tokyo_streetwear');
  });

  await test('Store Details profile contains all required tabs & stats', () => {
    const store = TEST_FIXTURE_STORES[0];
    assert.ok(store.shopify_shop_id, 'Shop ID must be present');
    assert.ok(store.owner_email, 'Owner email must be present');
    assert.ok(store.stats.productsCount >= 0, 'Synced products count must be present');
    assert.ok(store.stats.pixelsCount >= 0, 'Pixels count must be present');
    assert.ok(store.stats.eventsCount >= 0, 'CAPI events count must be present');
    assert.ok(store.billingHistory.length > 0, 'Billing history must be present');
    assert.ok(store.activityHistory.length > 0, 'Activity history must be present');
  });

  // --------------------------------------------------------------------------
  console.log('\n📦 4. Database Persistence & Table Schema Readiness:');
  // --------------------------------------------------------------------------

  await test('MySQL initialization creates admin_users, app_installations, subscriptions, billing_events, and store_activity_logs', async () => {
    await db.initialize();
    const admin = await db.getAdminUserByEmail('admin@meta-connector.app');
    assert.ok(admin, 'Default root admin user should exist in database');
    assert.strictEqual(admin.role, 'super_admin');
  });

  await test('MySQL records app installation and updates without duplicate shop records', async () => {
    const timestamp = Date.now();
    const testDomain = `unit-test-store-${timestamp}.myshopify.com`;
    const testShopId = 'shop_unit_test_' + timestamp;
    const now = new Date().toISOString();

    // 1. Initial install
    await db.upsertShop({
      id: testShopId,
      shopify_domain: testDomain,
      shopify_shop_id: 'gid://shopify/Shop/998877',
      shop_name: 'Unit Test Brand',
      owner_email: 'test@unit.com',
      owner_name: 'Test Owner',
      country: 'United States',
      currency: 'USD',
      billing_cycle: 'monthly',
      monthly_revenue: 13,
      access_token_encrypted: 'mock_enc_token',
      scopes: ['read_products'],
      installed_at: now,
      status: 'installed',
      plan: 'growth',
      created_at: now,
      updated_at: now,
    });

    const shop1 = await db.getShopByDomain(testDomain);
    assert.strictEqual(shop1?.status, 'installed');

    // 2. Record installation event
    await db.recordAppInstallation({
      id: `inst_${Date.now()}`,
      shop_id: testShopId,
      shopify_domain: testDomain,
      event_type: 'installed',
      plan_at_time: 'growth',
      occurred_at: now,
      created_at: now,
    });

    // 3. Uninstall
    await db.upsertShop({
      ...shop1!,
      status: 'uninstalled',
      uninstalled_at: now,
    });

    const shop2 = await db.getShopByDomain(testDomain);
    assert.strictEqual(shop2?.status, 'uninstalled');
    assert.ok(shop2?.uninstalled_at);

    // 4. Reinstall (must update existing shop, not create duplicate)
    await db.upsertShop({
      ...shop2!,
      status: 'installed',
      uninstalled_at: null,
    });

    const shop3 = await db.getShopByDomain(testDomain);
    assert.strictEqual(shop3?.status, 'installed');
    assert.strictEqual(shop3?.uninstalled_at, null);
    assert.strictEqual(shop3?.id, testShopId, 'Shop ID must remain identical upon reinstallation');
    try { await db.deleteShop(testShopId); } catch {}
  });

  await test('Store activity log and billing event recording', async () => {
    const testShopId = 'shop_unit_test_log';
    const now = new Date().toISOString();

    await db.recordStoreActivity({
      id: `act_test_${Date.now()}`,
      shop_id: testShopId,
      shopify_domain: 'log-test.myshopify.com',
      action: 'plan_upgraded',
      actor: 'merchant',
      description: 'Upgraded to Accelerate Tier ($99/mo)',
      created_at: now,
    });

    const logs = await db.getStoreActivityLogs(testShopId, 5);
    assert.ok(logs.length >= 1, 'Activity log should be saved and retrieved');
    assert.strictEqual(logs[0].action, 'plan_upgraded');

    await db.recordBillingEvent({
      id: `bill_test_${Date.now()}`,
      shop_id: testShopId,
      shopify_domain: 'log-test.myshopify.com',
      event_type: 'charge_activated',
      amount: 99,
      currency: 'USD',
      status: 'verified',
      billing_date: now,
      created_at: now,
    });

    const billingEvents = await db.getBillingEventsByShopId(testShopId);
    assert.ok(billingEvents.length >= 1, 'Billing event should be saved and retrieved');
    assert.strictEqual(billingEvents[0].amount, 99);
    try { await db.deleteShop(testShopId); } catch {}
  });

  console.log('\n======================================================');
  console.log(`🎉 SAAS ADMIN SUITE COMPLETED: ${passed}/${total} PASSED, ${total - passed} FAILED`);
  console.log('======================================================\n');

  if (passed !== total) {
    process.exit(1);
  }
}

runSaasAdminVerification().catch((err) => {
  console.error('Test runner failure:', err);
  process.exit(1);
});
