/**
 * E2E Tests for Team Management Feature
 *
 * Tests the complete team management workflow including:
 * - Team panel visibility for different tier users
 * - Invite member functionality for Business/Enterprise/Ultimate tiers
 * - Upgrade prompts for Starter/Professional tiers
 * - Seat limit enforcement
 * - Organization auto-creation
 *
 * This prevents regressions where:
 * - Users couldn't add staff members despite having the right plan
 * - Invite button wasn't visible for eligible users
 * - Upgrade prompts weren't shown for lower tier users
 */

import { test, expect, type Page } from '@playwright/test';

// Test user credentials (configured in the test environment)
const TEST_USER_TIER3 = {
  email: process.env.TEST_USER_TIER3_EMAIL || 'tier3test@mailinator.com',
};

const TEST_USER_TIER1 = {
  email: process.env.TEST_USER_TIER1_EMAIL || 'tier1test@mailinator.com',
};

test.describe('Team Management Feature', () => {
  test.describe('Team Panel UI Visibility', () => {
    test('should display Team tab in dashboard navigation for authenticated users', async ({
      page,
    }) => {
      // Navigate to dashboard
      await page.goto('/en/dashboard');

      // Check if redirected to login (if not authenticated)
      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated - skipping UI test');
        return;
      }

      // Look for Team tab in navigation
      const teamTab = page.locator('text=Team').or(page.locator('[data-tab="team"]'));

      // The tab should exist in navigation for users who can see it
      await expect(teamTab).toBeVisible({ timeout: 10000 }).catch(() => {
        // Tab might be hidden based on role - that's valid behavior
        console.log('Team tab not visible - user may not have access');
      });
    });

    test('should show Team Management heading when on team tab', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      // Wait for page load
      await page.waitForLoadState('networkidle');

      // Check for team management heading
      const teamHeading = page.locator('h1:has-text("Team Management"), h2:has-text("Team Management")');

      // If user has access to team tab, heading should be visible
      const isVisible = await teamHeading.isVisible().catch(() => false);
      if (isVisible) {
        await expect(teamHeading).toBeVisible();
      }
    });
  });

  test.describe('Tier-based Access Control', () => {
    test('should show upgrade prompt for Starter/Professional users', async ({ page }) => {
      // This test simulates what a tier1/tier2 user would see
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      // Look for upgrade-related text that appears for tier1/tier2 users
      const upgradePrompt = page.locator('text=Multi-staff not included').or(
        page.locator('text=Upgrade to Business')
      );

      const inviteButton = page.locator('button:has-text("Invite Member")');

      // Either upgrade prompt OR invite button should be visible
      // (depending on user's tier)
      const hasUpgradePrompt = await upgradePrompt.isVisible().catch(() => false);
      const hasInviteButton = await inviteButton.isVisible().catch(() => false);

      // At least one should be present for owners
      console.log('Has upgrade prompt:', hasUpgradePrompt);
      console.log('Has invite button:', hasInviteButton);
    });

    test('should show seat usage for Business/Enterprise/Ultimate users', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      // Look for seat usage indicators
      const seatUsageText = page.locator('text=Seats Used').or(page.locator('text=Available'));

      const isVisible = await seatUsageText.first().isVisible().catch(() => false);
      console.log('Seat usage visible:', isVisible);
    });
  });

  test.describe('Invite Member Functionality', () => {
    test('invite button should open form when clicked (for eligible users)', async ({
      page,
    }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      const inviteButton = page.locator('button:has-text("Invite Member")');

      const isVisible = await inviteButton.isVisible().catch(() => false);

      if (isVisible) {
        // Click the invite button
        await inviteButton.click();

        // Form should appear with email input
        const emailInput = page.locator('input[type="email"]').or(
          page.locator('input[placeholder*="email"]')
        );

        await expect(emailInput).toBeVisible({ timeout: 5000 });

        // Role selector should be visible
        const roleSelect = page.locator('select').first();
        await expect(roleSelect).toBeVisible();
      } else {
        console.log('Invite button not visible - user may be on lower tier or not owner');
      }
    });

    test('invite form should validate email format', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      const inviteButton = page.locator('button:has-text("Invite Member")');
      const isVisible = await inviteButton.isVisible().catch(() => false);

      if (!isVisible) {
        test.skip(true, 'Invite button not visible');
        return;
      }

      await inviteButton.click();

      // Try to submit with invalid email
      const emailInput = page.locator('input[type="email"]').first();
      await emailInput.fill('invalid-email');

      const submitButton = page.locator('button:has-text("Send Invitation")');
      await submitButton.click();

      // Should show validation error or not submit
      // HTML5 validation should prevent submission
      await page.waitForTimeout(500);

      // Check if still on the form (didn't submit)
      const formStillVisible = await page
        .locator('input[type="email"]')
        .first()
        .isVisible()
        .catch(() => false);
      expect(formStillVisible).toBe(true);
    });
  });

  test.describe('Team Members List', () => {
    test('should display team members section', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      // Look for team members section
      const teamMembersSection = page.locator('text=Team Members').first();

      const isVisible = await teamMembersSection.isVisible().catch(() => false);

      if (isVisible) {
        await expect(teamMembersSection).toBeVisible();

        // Should show either member list or empty state
        const emptyState = page.locator('text=No team members yet');
        const memberList = page.locator('[role="listitem"]').or(page.locator('.member-item'));

        const hasEmptyState = await emptyState.isVisible().catch(() => false);
        const hasMemberList = await memberList.first().isVisible().catch(() => false);

        // One of these should be true
        expect(hasEmptyState || hasMemberList).toBe(true);
      }
    });
  });

  test.describe('Seat Limit Enforcement', () => {
    test('should show seat limit warning when seats are full', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      // Look for seat limit warning
      const seatLimitWarning = page.locator('text=Seat limit reached').or(
        page.locator('text=Purchase additional seats')
      );

      const purchaseButton = page.locator('button:has-text("Purchase More Seats")');

      const hasWarning = await seatLimitWarning.isVisible().catch(() => false);
      const hasPurchaseButton = await purchaseButton.isVisible().catch(() => false);

      // If seats are full, both should be visible
      if (hasWarning) {
        console.log('Seat limit warning is displayed');
        // Purchase button should also be available
        expect(hasPurchaseButton).toBe(true);
      }
    });

    test('invite button should be disabled when no seats available', async ({ page }) => {
      await page.goto('/en/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      const inviteButton = page.locator('button:has-text("Invite Member")');
      const isVisible = await inviteButton.isVisible().catch(() => false);

      if (isVisible) {
        const isDisabled = await inviteButton.isDisabled().catch(() => false);

        // If button is disabled, check for seat limit message
        if (isDisabled) {
          const seatLimitMessage = page.locator('text=Seat limit').or(
            page.locator('text=0 Available')
          );
          const hasMessage = await seatLimitMessage.isVisible().catch(() => false);
          console.log('Invite button disabled, seat limit message:', hasMessage);
        }
      }
    });
  });

  test.describe('RTL Support (Arabic)', () => {
    test('should display team management correctly in Arabic', async ({ page }) => {
      await page.goto('/ar/dashboard?tab=team');

      const currentUrl = page.url();
      if (currentUrl.includes('/login')) {
        test.skip(true, 'User not authenticated');
        return;
      }

      await page.waitForLoadState('networkidle');

      // Check RTL direction
      const bodyDir = await page.getAttribute('body', 'dir').catch(() => null);
      const htmlDir = await page.locator('[dir="rtl"]').first().isVisible().catch(() => false);

      console.log('Body dir:', bodyDir, 'Has RTL element:', htmlDir);

      // Look for Arabic team management text
      const arabicText = page.locator('text=إدارة الفريق').or(page.locator('text=الفريق'));

      const hasArabicText = await arabicText.isVisible().catch(() => false);
      console.log('Arabic team text visible:', hasArabicText);
    });
  });
});

test.describe('API Integration Tests', () => {
  test('GET /api/organization/role should return valid response', async ({ request }) => {
    const response = await request.get('/api/organization/role');

    // Should return 200 or 401 (if not authenticated)
    expect([200, 401]).toContain(response.status());

    if (response.status() === 200) {
      const data = await response.json();
      expect(data).toHaveProperty('success');

      if (data.success) {
        // If successful, should have role info
        expect(data).toHaveProperty('role');
        expect(data).toHaveProperty('organizationId');
      }
    }
  });

  test('GET /api/organization/seats should return seat configuration', async ({ request }) => {
    const response = await request.get('/api/organization/seats');

    // Should return 200, 401, or 404
    expect([200, 401, 404]).toContain(response.status());

    if (response.status() === 200) {
      const data = await response.json();
      expect(data).toHaveProperty('success');

      if (data.success) {
        // Should have seat configuration
        expect(data).toHaveProperty('tierId');
        expect(data).toHaveProperty('includedSeats');
        expect(typeof data.includedSeats).toBe('number');
        expect(data).toHaveProperty('availableSeats');
        expect(typeof data.availableSeats).toBe('number');
      }
    }
  });

  test('GET /api/organization/members should return 401 or 403 for unauthorized', async ({
    request,
  }) => {
    const response = await request.get('/api/organization/members');

    // Should return 401 (not authenticated) or 403 (not authorized)
    expect([200, 401, 403, 404]).toContain(response.status());
  });

  test('POST /api/organization/members without auth should return 401', async ({ request }) => {
    const response = await request.post('/api/organization/members', {
      data: {
        email: 'test@example.com',
        role: 'STAFF',
      },
    });

    // Should return 401 for unauthenticated request
    expect([401, 403]).toContain(response.status());
  });
});

test.describe('Regression Tests', () => {
  test('team panel should not show empty state for users with organization', async ({
    page,
  }) => {
    await page.goto('/en/dashboard?tab=team');

    const currentUrl = page.url();
    if (currentUrl.includes('/login')) {
      test.skip(true, 'User not authenticated');
      return;
    }

    await page.waitForLoadState('networkidle');

    // Wait for data to load
    await page.waitForTimeout(2000);

    // Should not show loading skeleton after data loads
    const skeleton = page.locator('.animate-pulse');
    const skeletonVisible = await skeleton.isVisible().catch(() => false);

    // After loading, skeleton should not be visible
    if (skeletonVisible) {
      // Wait a bit more for loading to complete
      await page.waitForTimeout(3000);
      const stillLoading = await skeleton.isVisible().catch(() => false);
      console.log('Still loading after 5s:', stillLoading);
    }
  });

  test('organization should be auto-created for users with subscription', async ({
    request,
  }) => {
    // Make a request to the role API
    const roleResponse = await request.get('/api/organization/role');

    if (roleResponse.status() === 200) {
      const roleData = await roleResponse.json();

      if (roleData.success && roleData.role === 'OWNER') {
        // If user is OWNER, organization was created successfully
        expect(roleData.organizationId).toBeTruthy();

        // Verify seats API also works
        const seatsResponse = await request.get('/api/organization/seats');
        expect(seatsResponse.status()).toBe(200);

        const seatsData = await seatsResponse.json();
        expect(seatsData.success).toBe(true);
        expect(seatsData.tierId).toBeTruthy();
      }
    }
  });

  test('invite button visibility matches seat availability', async ({ page }) => {
    await page.goto('/en/dashboard?tab=team');

    const currentUrl = page.url();
    if (currentUrl.includes('/login')) {
      test.skip(true, 'User not authenticated');
      return;
    }

    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(2000);

    const inviteButton = page.locator('button:has-text("Invite Member")');
    const isButtonVisible = await inviteButton.isVisible().catch(() => false);

    if (isButtonVisible) {
      const isDisabled = await inviteButton.isDisabled().catch(() => false);

      // Check available seats text
      const availableText = await page.locator('text=/\\d+ Available/').textContent().catch(() => null);

      if (availableText) {
        const availableMatch = availableText.match(/(\d+)/);
        if (availableMatch) {
          const availableSeats = parseInt(availableMatch[1], 10);

          // Button should be disabled if 0 seats available
          if (availableSeats === 0) {
            expect(isDisabled).toBe(true);
          } else {
            expect(isDisabled).toBe(false);
          }
        }
      }
    }
  });
});
