/**
 * E2E Tests for Staff User Management Feature
 *
 * Tests the complete user management workflow including:
 * - Viewing user list
 * - Filtering and searching
 * - User details modal
 * - Account suspension/activation
 * - Admin notes
 * - Billing emails
 * - IP tracking display
 */

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

test.describe('Staff User Management', () => {
  let testStaffUser: any;
  let testCustomerUser: any;

  test.beforeAll(async () => {
    // Create test staff user
    testStaffUser = await prisma.users.create({
      data: {
        email: 'test-staff-um@mawidi.com',
        name: 'Test Staff User Management',
        username: 'test-staff-um',
        password: await import('bcryptjs').then((bcrypt) =>
          bcrypt.hashSync('TestPassword123!', 12)
        ),
        role: 'ADMIN',
        isActive: true,
      },
    });

    // Create test customer user with login data
    testCustomerUser = await prisma.users.create({
      data: {
        email: 'test-customer-um@example.com',
        name: 'Test Customer User',
        role: 'CUSTOMER',
        isActive: true,
        companyName: 'Test Company Ltd',
        industry: 'Healthcare',
        country: 'Qatar',
        city: 'Doha',
        lastLoginAt: new Date(),
        lastLoginIp: '203.0.113.100',
        lastLoginCountry: 'Qatar',
        lastLoginCity: 'Doha',
        loginCount: 15,
      },
    });

    // Create login history records
    await prisma.login_history.createMany({
      data: [
        {
          userId: testCustomerUser.id,
          ipAddress: '203.0.113.100',
          country: 'Qatar',
          countryCode: 'QA',
          city: 'Doha',
          provider: 'credentials',
          success: true,
        },
        {
          userId: testCustomerUser.id,
          ipAddress: '203.0.113.101',
          country: 'UAE',
          countryCode: 'AE',
          city: 'Dubai',
          provider: 'google',
          success: true,
        },
        {
          userId: testCustomerUser.id,
          ipAddress: '203.0.113.102',
          country: 'Qatar',
          countryCode: 'QA',
          city: 'Doha',
          provider: 'credentials',
          success: false,
          failReason: 'Invalid password',
        },
      ],
    });
  });

  test.afterAll(async () => {
    // Cleanup: Delete test users and related data
    await prisma.login_history.deleteMany({
      where: { userId: testCustomerUser.id },
    });

    await prisma.users.deleteMany({
      where: {
        email: { in: ['test-staff-um@mawidi.com', 'test-customer-um@example.com'] },
      },
    });
  });

  test('should display user management page for staff', async ({ page }) => {
    // Login as staff
    await page.goto('http://localhost:9000/staff/login');
    await page.fill('input[name="username"]', 'test-staff-um');
    await page.fill('input[name="password"]', 'TestPassword123!');
    await page.click('button[type="submit"]');

    // Wait for redirect to dashboard
    await page.waitForURL('**/staff/dashboard');

    // Navigate to users page
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Verify page loaded
    await expect(page.locator('h1')).toContainText('User Management');

    // Verify stats cards are visible
    await expect(page.locator('text=Total Users')).toBeVisible();
    await expect(page.locator('text=Active Users')).toBeVisible();
    await expect(page.locator('text=Suspended Users')).toBeVisible();
    await expect(page.locator('text=Locked Users')).toBeVisible();
  });

  test('should display users in table with IP and location', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for users table to load
    await page.waitForSelector('table', { timeout: 10000 });

    // Verify table headers
    await expect(page.locator('th:has-text("User")')).toBeVisible();
    await expect(page.locator('th:has-text("Location/IP")')).toBeVisible();
    await expect(page.locator('th:has-text("Activity")')).toBeVisible();

    // Verify our test user appears in the list
    const userRow = page.locator(`tr:has-text("${testCustomerUser.email}")`);
    await expect(userRow).toBeVisible();

    // Verify IP and location are displayed
    await expect(userRow.locator('text=203.0.113.100')).toBeVisible();
    await expect(userRow.locator('text=Qatar')).toBeVisible();
    await expect(userRow.locator('text=Doha')).toBeVisible();

    // Verify login count is displayed
    await expect(userRow.locator('text=15')).toBeVisible();
  });

  test('should filter users by status', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for filters to load
    await page.waitForSelector('select', { timeout: 5000 });

    // Find status filter dropdown
    const statusFilter = page.locator('select').first();

    // Filter to active users
    await statusFilter.selectOption('active');

    // Wait for results to update
    await page.waitForTimeout(1000);

    // Verify test user (active) is visible
    await expect(page.locator(`text=${testCustomerUser.email}`)).toBeVisible();
  });

  test('should search users by name or email', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Find search input
    const searchInput = page.locator('input[placeholder*="Search"]');
    await searchInput.fill('Test Customer');

    // Wait for filter to apply
    await page.waitForTimeout(500);

    // Verify filtered results
    await expect(page.locator(`text=${testCustomerUser.email}`)).toBeVisible();
  });

  test('should filter users by country', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for country filter
    await page.waitForSelector('select');

    // Find country filter (usually 4th select)
    const countryFilter = page.locator('select').nth(3);

    // Select Qatar
    await countryFilter.selectOption('Qatar');

    // Wait for filter to apply
    await page.waitForTimeout(1000);

    // Verify Qatar users are shown
    await expect(page.locator(`text=${testCustomerUser.email}`)).toBeVisible();
  });

  test('should toggle between list and map views', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Verify list view is default
    await expect(page.locator('table')).toBeVisible();

    // Click map view button
    await page.click('button:has-text("Map View")');

    // Verify map view is shown
    await expect(page.locator('table')).not.toBeVisible();
    await expect(page.locator('text=Users by Country')).toBeVisible();

    // Switch back to list view
    await page.click('button:has-text("List View")');

    // Verify table is back
    await expect(page.locator('table')).toBeVisible();
  });

  test('should open user detail modal on row click', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for table
    await page.waitForSelector('table');

    // Click on test user row
    await page.click(`tr:has-text("${testCustomerUser.email}")`);

    // Wait for modal to open
    await page.waitForSelector('[role="dialog"], .fixed.inset-0', { timeout: 5000 });

    // Verify modal title
    await expect(page.locator('text=' + testCustomerUser.name)).toBeVisible();

    // Verify tabs are present
    await expect(page.locator('text=Overview')).toBeVisible();
    await expect(page.locator('text=Login History')).toBeVisible();
    await expect(page.locator('text=Admin Notes')).toBeVisible();
    await expect(page.locator('text=Billing')).toBeVisible();
    await expect(page.locator('text=Actions')).toBeVisible();
  });

  test('should display login history in modal', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open user modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Click Login History tab
    await page.click('button:has-text("Login History")');

    // Wait for content to load
    await page.waitForTimeout(1000);

    // Verify login history entries are displayed
    await expect(page.locator('text=203.0.113.100')).toBeVisible();
    await expect(page.locator('text=Qatar')).toBeVisible();
    await expect(page.locator('text=Doha')).toBeVisible();

    // Verify multiple login locations
    await expect(page.locator('text=Dubai')).toBeVisible();
  });

  test('should add admin note to user', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open user modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Click Admin Notes tab
    await page.click('button:has-text("Admin Notes")');

    // Wait for tab content
    await page.waitForTimeout(500);

    // Fill note form
    const noteContent = 'Test admin note for E2E testing';
    await page.fill('textarea', noteContent);

    // Select category
    await page.selectOption('select', 'SUPPORT');

    // Submit note
    await page.click('button:has-text("Add Note")');

    // Wait for success
    await page.waitForTimeout(1000);

    // Verify note was added (should appear in list or show success)
    // Note: This will depend on your UI implementation
  });

  test('should suspend user account (admin only)', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open user modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Click Actions tab
    await page.click('button:has-text("Actions")');

    // Wait for content
    await page.waitForTimeout(500);

    // Fill suspension reason
    const reason = 'Testing account suspension feature in E2E test';
    await page.fill('textarea', reason);

    // Click suspend button
    const suspendButton = page.locator('button:has-text("Suspend Account")');
    await expect(suspendButton).toBeVisible();

    // Handle confirmation dialog
    page.on('dialog', (dialog) => dialog.accept());

    await suspendButton.click();

    // Wait for action to complete
    await page.waitForTimeout(2000);

    // Modal should close
    // Re-open to verify status changed
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Should show suspended badge
    await expect(page.locator('text=Suspended').or(page.locator('text=suspended'))).toBeVisible();
  });

  test('should activate suspended account (admin only)', async ({ page }) => {
    // Ensure user is suspended first
    await prisma.users.update({
      where: { id: testCustomerUser.id },
      data: {
        isSuspended: true,
        isActive: false,
        suspendedReason: 'Test suspension',
      },
    });

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

    // Open user modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Go to Actions tab
    await page.click('button:has-text("Actions")');
    await page.waitForTimeout(500);

    // Click activate button
    const activateButton = page.locator('button:has-text("Activate Account")');
    await expect(activateButton).toBeVisible();

    // Handle confirmation
    page.on('dialog', (dialog) => dialog.accept());

    await activateButton.click();

    // Wait for completion
    await page.waitForTimeout(2000);

    // Verify user is now active
    const updatedUser = await prisma.users.findUnique({
      where: { id: testCustomerUser.id },
      select: { isActive: true, isSuspended: true },
    });

    expect(updatedUser?.isActive).toBe(true);
    expect(updatedUser?.isSuspended).toBe(false);
  });

  test('should copy email and IP to clipboard', async ({ page, context }) => {
    // Grant clipboard permissions
    await context.grantPermissions(['clipboard-read', 'clipboard-write']);

    await page.goto('http://localhost:9000/staff/dashboard/users');
    await page.waitForSelector('table');

    // Find copy button for email
    const emailCopyButton = page
      .locator(`tr:has-text("${testCustomerUser.email}")`)
      .locator('button[title*="Copy"]')
      .first();

    await emailCopyButton.click();

    // Verify clipboard contains email
    const clipboardText = await page.evaluate(() => navigator.clipboard.readText());
    expect(clipboardText).toBe(testCustomerUser.email);

    // Verify check icon appears briefly
    await expect(page.locator('svg.lucide-check')).toBeVisible();
    await page.waitForTimeout(2500);
    await expect(page.locator('svg.lucide-check')).not.toBeVisible();
  });

  test('should export users to CSV', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Setup download listener
    const downloadPromise = page.waitForEvent('download');

    // Click export button
    await page.click('button:has-text("Export CSV")');

    // Wait for download
    const download = await downloadPromise;

    // Verify filename
    expect(download.suggestedFilename()).toMatch(/users-export-\d{4}-\d{2}-\d{2}\.csv/);

    // Verify file content
    const path = await download.path();
    const fs = await import('fs/promises');
    const content = await fs.readFile(path, 'utf-8');

    // Should contain headers
    expect(content).toContain('Name,Email');
    expect(content).toContain('Login Count');

    // Should contain our test user
    expect(content).toContain(testCustomerUser.email);
  });

  test('should auto-refresh when enabled', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Enable auto-refresh
    const autoRefreshCheckbox = page.locator('input[type="checkbox"]');
    await autoRefreshCheckbox.check();

    // Verify checkbox is checked
    await expect(autoRefreshCheckbox).toBeChecked();

    // Wait a bit and verify refresh happens
    // (This is hard to test directly, but we can verify the checkbox stays checked)
    await page.waitForTimeout(2000);
    await expect(autoRefreshCheckbox).toBeChecked();
  });

  test('should show loading state initially', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Should show loading spinner initially
    const loadingSpinner = page.locator('.animate-spin');
    const isVisible = await loadingSpinner.isVisible().catch(() => false);

    // It might load too fast, so we just verify the page loads successfully
    await expect(page.locator('h1')).toContainText('User Management');
  });

  test('should clear all filters', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Apply filters
    await page.fill('input[placeholder*="Search"]', 'test');
    await page.selectOption('select >> nth=0', 'active');

    // Wait for filters to apply
    await page.waitForTimeout(500);

    // Click clear filters button
    await page.click('button:has-text("Clear")');

    // Verify filters are cleared
    const searchInput = page.locator('input[placeholder*="Search"]');
    await expect(searchInput).toHaveValue('');
  });

  test('should display geography map view', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Switch to map view
    await page.click('button:has-text("Map View")');

    // Verify map content
    await expect(page.locator('text=Users by Country')).toBeVisible();
    await expect(page.locator('text=Qatar')).toBeVisible();

    // Should show user counts
    await expect(page.locator('text=user').or(page.locator('text=1'))).toBeVisible();
  });

  test('should filter by country when clicking on map', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Go to map view
    await page.click('button:has-text("Map View")');
    await page.waitForTimeout(500);

    // Click on Qatar
    await page.click('text=Qatar >> .. >> button');

    // Should switch back to list view and filter by Qatar
    await expect(page.locator('table')).toBeVisible();

    // Verify country filter is applied
    // (Implementation dependent - may show in select or results)
  });

  test('should show user count in results summary', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for page load
    await page.waitForSelector('table');

    // Find results count text
    const resultsText = page.locator('text=Showing');
    await expect(resultsText).toBeVisible();

    // Should show "Showing X of Y users"
    await expect(resultsText).toContainText('of');
    await expect(resultsText).toContainText('users');
  });

  test('should handle unauthorized access gracefully', async ({ page }) => {
    // Try to access without authentication
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Should redirect to login
    await page.waitForURL('**/staff/login', { timeout: 5000 });

    expect(page.url()).toContain('/staff/login');
  });

  test('should send billing email to user', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open user modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Go to Billing tab
    await page.click('button:has-text("Billing")');
    await page.waitForTimeout(500);

    // Fill billing form
    await page.fill('input[placeholder*="Subject"]', 'Test Invoice');
    await page.fill('textarea', 'This is a test billing email message for E2E testing');

    // Click send button
    await page.click('button:has-text("Send Email")');

    // Wait for completion
    await page.waitForTimeout(2000);

    // Verify success (check for alert or success message)
    // This depends on your implementation
  });

  test('should refresh data manually', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Click refresh button
    const refreshButton = page.locator('button:has-text("Refresh")');
    await refreshButton.click();

    // Verify spinner appears
    const spinner = page.locator('.animate-spin');
    await expect(spinner).toBeVisible();

    // Wait for refresh to complete
    await page.waitForTimeout(2000);

    // Spinner should be gone
    await expect(spinner).not.toBeVisible();
  });

  test('should show empty state when no users match filters', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Search for non-existent user
    await page.fill('input[placeholder*="Search"]', 'definitely-does-not-exist-xyz-123');

    // Wait for filter to apply
    await page.waitForTimeout(1000);

    // Should show empty state
    await expect(page.locator('text=No users found')).toBeVisible();
  });

  test('should display account status badges correctly', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Wait for table
    await page.waitForSelector('table');

    // Find test user row
    const userRow = page.locator(`tr:has-text("${testCustomerUser.email}")`);

    // Verify status badge is present
    // (Color and text depend on account status)
    const statusBadge = userRow.locator('[class*="bg-green"], [class*="bg-orange"], [class*="bg-red"]');
    await expect(statusBadge).toBeVisible();
  });

  test('should close modal when clicking X button', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Click X button
    await page.click('button[aria-label="Close"], button:has(svg.lucide-x)');

    // Modal should close
    await expect(page.locator('[role="dialog"], .fixed.inset-0')).not.toBeVisible();
  });

  test('should validate suspension reason length', async ({ page }) => {
    await page.goto('http://localhost:9000/staff/dashboard/users');

    // Open modal
    await page.click(`tr:has-text("${testCustomerUser.email}")`);
    await page.waitForSelector('[role="dialog"], .fixed.inset-0');

    // Go to Actions tab
    await page.click('button:has-text("Actions")');
    await page.waitForTimeout(500);

    // Try to suspend with short reason
    await page.fill('textarea', 'Bad'); // Too short

    // Setup dialog handler
    page.on('dialog', (dialog) => dialog.accept());

    // Click suspend
    await page.click('button:has-text("Suspend Account")');

    // Should show error alert
    await page.waitForTimeout(500);
    // Alert would have been handled by dialog listener
  });
});

describe('User Management Integration Tests', () => {
  test('should update loginCount when user logs in', async () => {
    const initialUser = await prisma.users.findUnique({
      where: { email: 'test-customer-um@example.com' },
      select: { loginCount: true },
    });

    const initialCount = initialUser?.loginCount || 0;

    // Simulate login by updating user
    await prisma.users.update({
      where: { email: 'test-customer-um@example.com' },
      data: {
        lastLoginAt: new Date(),
        loginCount: { increment: 1 },
      },
    });

    const updatedUser = await prisma.users.findUnique({
      where: { email: 'test-customer-um@example.com' },
      select: { loginCount: true },
    });

    expect(updatedUser?.loginCount).toBe(initialCount + 1);
  });

  test('should create login history on each login', async () => {
    const beforeCount = await prisma.login_history.count({
      where: { userId: testCustomerUser.id },
    });

    // Create new login history
    await prisma.login_history.create({
      data: {
        userId: testCustomerUser.id,
        ipAddress: '203.0.113.200',
        country: 'Saudi Arabia',
        countryCode: 'SA',
        city: 'Riyadh',
        provider: 'google',
        success: true,
      },
    });

    const afterCount = await prisma.login_history.count({
      where: { userId: testCustomerUser.id },
    });

    expect(afterCount).toBe(beforeCount + 1);
  });

  test('should block login for suspended users', async () => {
    // Suspend the test user
    await prisma.users.update({
      where: { id: testCustomerUser.id },
      data: {
        isSuspended: true,
        isActive: false,
        suspendedReason: 'Test suspension for E2E',
      },
    });

    const user = await prisma.users.findUnique({
      where: { id: testCustomerUser.id },
      select: { isSuspended: true },
    });

    expect(user?.isSuspended).toBe(true);

    // Reactivate for cleanup
    await prisma.users.update({
      where: { id: testCustomerUser.id },
      data: {
        isSuspended: false,
        isActive: true,
        suspendedReason: null,
      },
    });
  });
});
