/**
 * E2E Tests for Subscription Upgrade/Downgrade
 * Tests the complete user flow from dashboard to plan change confirmation
 */

import { test, expect } from '@playwright/test';
import { prisma } from '@/lib/db';

// Test user credentials
const TEST_USER = {
  email: 'e2e-billing@example.com',
  password: 'TestPassword123!@#',
  name: 'E2E Billing Test User',
};

test.describe('Subscription Upgrade/Downgrade Flow', () => {
  let userId: string;
  let subscriptionId: string;

  test.beforeAll(async () => {
    // Create test user with active subscription
    const user = await prisma.users.create({
      data: {
        email: TEST_USER.email,
        name: TEST_USER.name,
        password: TEST_USER.password,
        stripeCustomerId: 'cus_e2e_billing_test',
        role: 'CUSTOMER',
        emailVerified: new Date(),
      },
    });

    userId = user.id;

    // Create active subscription on tier2 (Professional)
    const subscription = await prisma.subscriptions.create({
      data: {
        userId: user.id,
        stripeCustomerId: 'cus_e2e_billing_test',
        stripeSubscriptionId: 'sub_e2e_billing_test',
        stripePriceId: 'price_professional_monthly',
        tierId: 'tier2',
        status: 'active',
        billingPeriod: 'monthly',
        currentPeriodEnd: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000), // 14 days from now
        setupFeePaid: true,
        setupFeeAmount: 199,
      },
    });

    subscriptionId = subscription.id;
  });

  test.afterAll(async () => {
    // Cleanup
    if (subscriptionId) {
      await prisma.subscriptions.delete({ where: { id: subscriptionId } });
    }
    if (userId) {
      await prisma.audit_logs.deleteMany({ where: { userId } });
      await prisma.users.delete({ where: { id: userId } });
    }
  });

  test.describe('Dashboard Billing Panel', () => {
    test('should display current subscription correctly', async ({ page }) => {
      // Login (assuming login flow exists)
      await page.goto('http://localhost:9000/en/login');
      await page.fill('input[name="email"]', TEST_USER.email);
      await page.fill('input[name="password"]', TEST_USER.password);
      await page.click('button[type="submit"]');

      // Wait for dashboard
      await page.waitForURL(/.*dashboard.*/);

      // Navigate to billing section
      await page.goto('http://localhost:9000/en/dashboard');

      // Verify current plan is displayed
      await expect(page.getByText('Professional')).toBeVisible();
      await expect(page.getByText(/You are currently on/i)).toBeVisible();
      await expect(page.getByText(/Active/i)).toBeVisible();

      // Verify days remaining is shown
      await expect(page.getByText(/days remaining/i)).toBeVisible();

      // Verify setup fee paid indicator
      await expect(page.getByText(/Setup fee already paid/i)).toBeVisible();
    });

    test('should show available upgrades section', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Should show upgrades section (tier3, tier4, tier5 available)
      await expect(page.getByText('Available Upgrades')).toBeVisible();

      // Should show upgrade options
      await expect(page.getByText('Business')).toBeVisible();
      await expect(page.getByText('Enterprise')).toBeVisible();

      // Should show prorated charges
      await expect(page.getByText(/Prorated upgrade fee/i)).toBeVisible();
    });

    test('should show available downgrades section', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Should show downgrades section (tier1 available)
      await expect(page.getByText('Downgrade Options')).toBeVisible();

      // Should show downgrade option
      await expect(page.getByText('Starter')).toBeVisible();

      // Should show credit information
      await expect(page.getByText(/Credit:/i)).toBeVisible();
      await expect(page.getByText(/Next bill:/i)).toBeVisible();
    });
  });

  test.describe('Upgrade Flow', () => {
    test('should complete upgrade with proration preview', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Find and click upgrade button for Business tier
      await page.click('button:has-text("Upgrade to Business")');

      // Verify modal opened
      await expect(page.getByText('Upgrade your plan')).toBeVisible();

      // Verify tier selection
      await expect(page.getByText('Business')).toBeVisible();

      // Verify proration preview is shown
      await expect(page.getByText(/Due today/i)).toBeVisible();
      await expect(page.getByText(/Invoice breakdown/i)).toBeVisible();

      // Check for proration indicator
      await expect(page.getByText(/proration/i)).toBeVisible();

      // Verify next renewal date shown
      await expect(page.getByText(/Next renewal will be on/i)).toBeVisible();

      // Note: Don't actually confirm upgrade in test (would need Stripe test mode)
      // await page.click('button:has-text("Confirm upgrade")');

      // Close modal instead
      await page.click('button:has-text("Cancel")');
      await expect(page.getByText('Upgrade your plan')).not.toBeVisible();
    });

    test('should show upgrade button in billing panel', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Main upgrade button should be visible
      await expect(page.getByRole('button', { name: /Upgrade Plan/i })).toBeVisible();

      // Click main upgrade button
      await page.click('button:has-text("Upgrade Plan")');

      // Modal should open
      await expect(page.getByText('Upgrade your plan')).toBeVisible();
    });

    test('should prevent upgrade to same tier', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Current tier is tier2 (Professional)
      // There should be no "Upgrade to Professional" button
      const upgradeToProfessional = page.getByRole('button', { name: /Upgrade to Professional/i });
      await expect(upgradeToProfessional).not.toBeVisible();
    });
  });

  test.describe('Downgrade Flow', () => {
    test('should complete downgrade with credit preview', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Scroll to downgrade section
      await page.evaluate(() => {
        document.querySelector('h3:has-text("Downgrade Options")')?.scrollIntoView();
      });

      // Find and click downgrade button for Starter tier
      await page.click('button:has-text("Downgrade to Starter")');

      // Verify modal opened
      await expect(page.getByText('Downgrade your plan')).toBeVisible();

      // Verify credit message
      await expect(page.getByText(/Credit will be applied/i)).toBeVisible();

      // Verify tier selection shows Starter
      await expect(page.getByText('Starter')).toBeVisible();

      // Verify proration preview shows credit
      await expect(page.getByText(/Due today/i)).toBeVisible();

      // Note: Don't actually confirm downgrade in test
      // Close modal
      await page.click('button:has-text("Cancel")');
      await expect(page.getByText('Downgrade your plan')).not.toBeVisible();
    });

    test('should show credit calculation in downgrade cards', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Navigate to downgrade section
      const downgradeSection = page.locator('text=Downgrade Options').locator('..');

      // Verify credit amount is displayed
      await expect(downgradeSection.getByText(/Credit:/i)).toBeVisible();

      // Verify next bill calculation is shown
      await expect(downgradeSection.getByText(/Next bill:/i)).toBeVisible();

      // Verify explanatory text about credit
      await expect(page.getByText(/Remaining credit will be applied/i)).toBeVisible();
    });

    test('should show correct downgrade options based on current tier', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Current tier is tier2 (Professional)
      // Should only show tier1 (Starter) as downgrade option
      await expect(page.getByText('Downgrade to Starter')).toBeVisible();

      // Should NOT show Professional as downgrade (current tier)
      const downgradeToProfessional = page.getByRole('button', { name: /Downgrade to Professional/i });
      await expect(downgradeToProfessional).not.toBeVisible();
    });
  });

  test.describe('Bilingual Support', () => {
    test('should display upgrade UI in Arabic correctly', async ({ page }) => {
      await page.goto('http://localhost:9000/ar/dashboard');

      // Verify Arabic text for upgrades
      await expect(page.getByText('ترقيات متاحة')).toBeVisible();

      // Verify Arabic tier names
      await expect(page.getByText('الأعمال')).toBeVisible(); // Business in Arabic

      // Verify Arabic pricing text
      await expect(page.getByText(/رسوم الترقية المقسمة/i)).toBeVisible();
    });

    test('should display downgrade UI in Arabic correctly', async ({ page }) => {
      await page.goto('http://localhost:9000/ar/dashboard');

      // Verify Arabic text for downgrades
      await expect(page.getByText('خيارات التخفيض')).toBeVisible();

      // Verify Arabic credit text
      await expect(page.getByText(/رصيد متبقي/i)).toBeVisible();

      // Verify Arabic next bill text
      await expect(page.getByText(/الفاتورة القادمة/i)).toBeVisible();
    });
  });

  test.describe('Responsive Design', () => {
    test('should display correctly on mobile (iPhone 12)', async ({ page }) => {
      await page.setViewportSize({ width: 390, height: 844 });
      await page.goto('http://localhost:9000/en/dashboard');

      // Billing panel should be visible
      await expect(page.getByText('You are currently on')).toBeVisible();

      // Cards should stack vertically
      const upgradeCards = page.locator('text=Upgrade to').locator('..');
      const count = await upgradeCards.count();
      expect(count).toBeGreaterThan(0);
    });

    test('should display correctly on tablet (iPad)', async ({ page }) => {
      await page.setViewportSize({ width: 768, height: 1024 });
      await page.goto('http://localhost:9000/en/dashboard');

      // Should show 2-column grid
      await expect(page.getByText('Available Upgrades')).toBeVisible();
    });

    test('should display correctly on desktop', async ({ page }) => {
      await page.setViewportSize({ width: 1920, height: 1080 });
      await page.goto('http://localhost:9000/en/dashboard');

      // All sections should be visible without scrolling
      await expect(page.getByText('You are currently on')).toBeVisible();
      await expect(page.getByText('Available Upgrades')).toBeVisible();
    });
  });

  test.describe('Security', () => {
    test('should require authentication to view billing', async ({ page }) => {
      // Try to access dashboard without login
      await page.goto('http://localhost:9000/en/dashboard');

      // Should redirect to login or show unauthorized
      await page.waitForURL(/.*login.*/);
    });

    test('should protect billing API endpoints', async ({ page }) => {
      // Try to call API without authentication
      const response = await page.request.post('http://localhost:9000/api/billing/change-plan', {
        data: {
          newPlanType: 'professional',
        },
      });

      expect(response.status()).toBe(401);
    });
  });

  test.describe('Error Handling', () => {
    test('should handle network errors gracefully', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Mock network failure
      await page.route('**/api/billing/change-plan', route => route.abort());

      // Try to upgrade
      await page.click('button:has-text("Upgrade to Business")').catch(() => {});

      // Modal should still be functional
      await page.click('button:has-text("Cancel")').catch(() => {});
    });

    test('should display error messages in user language', async ({ page }) => {
      // Test in English
      await page.goto('http://localhost:9000/en/dashboard');
      // Error messages would be in English

      // Test in Arabic
      await page.goto('http://localhost:9000/ar/dashboard');
      // Error messages would be in Arabic
    });
  });

  test.describe('Visual Regression', () => {
    test('should match upgrade section screenshot', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Take screenshot of upgrade section
      const upgradeSection = page.locator('text=Available Upgrades').locator('..');
      await expect(upgradeSection).toHaveScreenshot('upgrade-section.png');
    });

    test('should match downgrade section screenshot', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Take screenshot of downgrade section
      const downgradeSection = page.locator('text=Downgrade Options').locator('..');
      await expect(downgradeSection).toHaveScreenshot('downgrade-section.png');
    });

    test('should match upgrade modal screenshot', async ({ page }) => {
      await page.goto('http://localhost:9000/en/dashboard');

      // Open upgrade modal
      await page.click('button:has-text("Upgrade to Business")');

      // Wait for modal animation
      await page.waitForTimeout(300);

      // Take screenshot
      const modal = page.locator('text=Upgrade your plan').locator('..');
      await expect(modal).toHaveScreenshot('upgrade-modal.png');
    });
  });
});

test.describe('Upgrade Flow - Complete Journey', () => {
  test('should show correct proration amounts for different tiers', async ({ page }) => {
    // This test verifies the UI shows consistent proration calculations
    await page.goto('http://localhost:9000/en/dashboard');

    // Check tier3 upgrade shows proration
    const businessCard = page.locator('text=Business').locator('..');
    await expect(businessCard.getByText(/Prorated upgrade fee/i)).toBeVisible();

    // Check tier4 upgrade shows proration
    const enterpriseCard = page.locator('text=Enterprise').locator('..');
    await expect(enterpriseCard.getByText(/Prorated upgrade fee/i)).toBeVisible();

    // Verify amounts are displayed in correct currency
    await expect(page.getByText(/GBP|USD|SAR|AED|QAR/i)).toBeVisible();
  });

  test('should update UI after successful plan change', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Current plan should show Professional
    await expect(page.getByText(/You are currently on.*Professional/i)).toBeVisible();

    // Note: In real test with Stripe, we would:
    // 1. Click upgrade
    // 2. Confirm
    // 3. Wait for webhook
    // 4. Verify UI updates to show new tier
  });
});

test.describe('Downgrade Flow - Complete Journey', () => {
  test('should show credit information clearly', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Find Starter downgrade card
    const starterCard = page.locator('text=Downgrade to Starter').locator('..');

    // Verify credit amount is visible
    await expect(starterCard.getByText(/Credit:/i)).toBeVisible();

    // Verify next billing amount is visible
    await expect(starterCard.getByText(/Next bill:/i)).toBeVisible();

    // Verify explanatory text
    await expect(page.getByText(/Remaining credit will be applied/i)).toBeVisible();
  });

  test('should maintain features until period end message', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Open downgrade modal
    await page.click('button:has-text("Downgrade to Starter")');

    // Verify message about keeping features
    await expect(page.getByText(/keep features until the end/i)).toBeVisible();
  });
});

test.describe('Accessibility', () => {
  test('should be keyboard navigable', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Tab through upgrade buttons
    await page.keyboard.press('Tab');
    await page.keyboard.press('Tab');

    // Should be able to activate with Enter
    const focusedElement = await page.locator(':focus').textContent();
    expect(focusedElement).toBeTruthy();
  });

  test('should have proper ARIA labels', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Buttons should have accessible names
    const upgradeButtons = page.getByRole('button', { name: /Upgrade to/i });
    expect(await upgradeButtons.count()).toBeGreaterThan(0);

    const downgradeButtons = page.getByRole('button', { name: /Downgrade to/i });
    expect(await downgradeButtons.count()).toBeGreaterThan(0);
  });

  test('should have sufficient color contrast', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    // Test high-contrast mode
    await page.emulateMedia({ colorScheme: 'dark' });

    // Elements should still be visible
    await expect(page.getByText('Available Upgrades')).toBeVisible();
  });
});

test.describe('Performance', () => {
  test('should load billing panel within 2 seconds', async ({ page }) => {
    const startTime = Date.now();

    await page.goto('http://localhost:9000/en/dashboard');

    // Wait for billing content to load
    await page.waitForSelector('text=You are currently on');

    const loadTime = Date.now() - startTime;

    expect(loadTime).toBeLessThan(2000);
  });

  test('should calculate proration preview within 1 second', async ({ page }) => {
    await page.goto('http://localhost:9000/en/dashboard');

    const startTime = Date.now();

    // Open modal
    await page.click('button:has-text("Upgrade to Business")');

    // Wait for proration preview
    await page.waitForSelector('text=Due today');

    const previewTime = Date.now() - startTime;

    expect(previewTime).toBeLessThan(1000);
  });
});
