/**
 * Authentication & API mocking helper for E2E tests
 * Provides mock API responses for testing authenticated pages
 * without requiring a real backend
 */

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

/**
 * Mock user data for E2E testing
 */
export const MOCK_USER = {
  id: '00000000-0000-0000-0000-000000000001',
  email: 'test@example.com',
  first_name: 'Test',
  last_name: 'User',
  phone_number: null,
  is_active: true,
  is_superuser: false,
  created_at: new Date().toISOString(),
  updated_at: new Date().toISOString(),
};

/**
 * Mock session data for E2E testing
 */
export const MOCK_SESSION = {
  id: '00000000-0000-0000-0000-000000000002',
  device_type: 'Desktop',
  device_name: 'Chrome on Linux',
  ip_address: '127.0.0.1',
  location: 'Local',
  last_used_at: new Date().toISOString(),
  created_at: new Date().toISOString(),
  is_current: true,
};

/**
 * Mock superuser data for E2E testing
 */
export const MOCK_SUPERUSER = {
  id: '00000000-0000-0000-0000-000000000003',
  email: 'admin@example.com',
  first_name: 'Admin',
  last_name: 'User',
  phone_number: null,
  is_active: true,
  is_superuser: true,
  created_at: new Date().toISOString(),
  updated_at: new Date().toISOString(),
};

/**
 * Mock organization data for E2E testing
 */
export const MOCK_ORGANIZATIONS = [
  {
    id: '00000000-0000-0000-0000-000000000101',
    name: 'Acme Corporation',
    slug: 'acme-corporation',
    description: 'Leading provider of innovative solutions',
    is_active: true,
    created_at: new Date('2025-01-01').toISOString(),
    updated_at: new Date('2025-01-01').toISOString(),
    member_count: 15,
  },
  {
    id: '00000000-0000-0000-0000-000000000102',
    name: 'Tech Startup Inc',
    slug: 'tech-startup-inc',
    description: 'Building the future of technology',
    is_active: false,
    created_at: new Date('2025-01-15').toISOString(),
    updated_at: new Date('2025-01-15').toISOString(),
    member_count: 3,
  },
  {
    id: '00000000-0000-0000-0000-000000000103',
    name: 'Global Enterprises',
    slug: 'global-enterprises',
    description: null,
    is_active: true,
    created_at: new Date('2025-02-01').toISOString(),
    updated_at: new Date('2025-02-01').toISOString(),
    member_count: 42,
  },
];

/**
 * Authenticate user via REAL login flow
 * Tests actual user behavior: fill form → submit → API call → store tokens → redirect
 * Requires setupAuthenticatedMocks() to be called first
 *
 * @param page Playwright page object
 * @param email User email (defaults to mock user email)
 * @param password User password (defaults to mock password)
 */
export async function loginViaUI(
  page: Page,
  email = 'test@example.com',
  password = 'Password123!'
): Promise<void> {
  // Navigate to login page (with locale prefix)
  await page.goto('/en/login');

  // Fill login form
  await page.locator('input[name="email"]').fill(email);
  await page.locator('input[name="password"]').fill(password);

  // Submit and wait for navigation to home (with locale prefix)
  await Promise.all([page.waitForURL('/en'), page.locator('button[type="submit"]').click()]);

  // Wait for auth to settle
  await page.waitForTimeout(500);
}

/**
 * Set up API mocking for authenticated E2E tests
 * Intercepts backend API calls and returns mock data
 * Routes persist across client-side navigation
 *
 * @param page Playwright page object
 */
export async function setupAuthenticatedMocks(page: Page): Promise<void> {
  // Set E2E test mode flag to skip encryption in storage.ts
  await page.addInitScript(() => {
    (window as any).__PLAYWRIGHT_TEST__ = true;
  });

  const baseURL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000';

  // Mock POST /api/v1/auth/login - Login endpoint
  await page.route(`${baseURL}/api/v1/auth/login`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          user: MOCK_USER,
          access_token:
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDEiLCJleHAiOjk5OTk5OTk5OTl9.signature',
          refresh_token:
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDIiLCJleHAiOjk5OTk5OTk5OTl9.signature',
          expires_in: 3600,
          token_type: 'bearer',
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/users/me - Get current user
  // Mock PATCH /api/v1/users/me - Update user profile
  await page.route(`${baseURL}/api/v1/users/me`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(MOCK_USER),
      });
    } else if (route.request().method() === 'PATCH') {
      const postData = route.request().postDataJSON();
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ ...MOCK_USER, ...postData }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/auth/change-password - Change password
  await page.route(`${baseURL}/api/v1/auth/change-password`, async (route: Route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        message: 'Password changed successfully',
      }),
    });
  });

  // Mock GET /api/v1/sessions - Get user sessions
  await page.route(`${baseURL}/api/v1/sessions**`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          sessions: [MOCK_SESSION],
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock DELETE /api/v1/sessions/:id - Revoke session
  await page.route(`${baseURL}/api/v1/sessions/*`, async (route: Route) => {
    if (route.request().method() === 'DELETE') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          message: 'Session revoked successfully',
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/auth/logout - Logout endpoint
  await page.route(`${baseURL}/api/v1/auth/logout`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          message: 'Logged out successfully',
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/oauth/providers - Get available OAuth providers
  await page.route(`${baseURL}/api/v1/oauth/providers`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          enabled: true,
          providers: [
            { provider: 'google', name: 'Google' },
            { provider: 'github', name: 'GitHub' },
          ],
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/oauth/authorize/:provider - Get OAuth authorization URL
  await page.route(`${baseURL}/api/v1/oauth/authorize/*`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      const url = route.request().url();
      const provider = url.match(/authorize\/(\w+)/)?.[1] || 'google';
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          authorization_url: `https://mock-oauth.example.com/authorize?provider=${provider}`,
          state: 'mock-state-token',
        }),
      });
    } else {
      await route.continue();
    }
  });

  /**
   * E2E tests now use the REAL auth store with mocked API routes.
   * We inject authentication by calling setAuth() directly in the page context.
   * This tests the actual production code path including encryption.
   */
}

/**
 * Set up API mocking for superuser E2E tests
 * Similar to setupAuthenticatedMocks but returns MOCK_SUPERUSER instead
 * Also mocks admin endpoints for stats display
 *
 * @param page Playwright page object
 */
export async function setupSuperuserMocks(page: Page): Promise<void> {
  // Set E2E test mode flag
  await page.addInitScript(() => {
    (window as any).__PLAYWRIGHT_TEST__ = true;
  });

  const baseURL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000';

  // Mock POST /api/v1/auth/login - Login endpoint (returns superuser)
  await page.route(`${baseURL}/api/v1/auth/login`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          user: MOCK_SUPERUSER,
          access_token:
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDMiLCJleHAiOjk5OTk5OTk5OTl9.signature',
          refresh_token:
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDQiLCJleHAiOjk5OTk5OTk5OTl9.signature',
          expires_in: 3600,
          token_type: 'bearer',
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/users/me - Get current user (superuser)
  await page.route(`${baseURL}/api/v1/users/me`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(MOCK_SUPERUSER),
      });
    } else if (route.request().method() === 'PATCH') {
      const postData = route.request().postDataJSON();
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ ...MOCK_SUPERUSER, ...postData }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/users - Get all users (admin endpoint)
  await page.route(`${baseURL}/api/v1/admin/users*`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          data: [MOCK_USER, MOCK_SUPERUSER],
          pagination: {
            total: 2,
            page: 1,
            page_size: 50,
            total_pages: 1,
          },
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/organizations - Get all organizations (admin endpoint)
  await page.route(`${baseURL}/api/v1/admin/organizations*`, async (route: Route) => {
    const url = route.request().url();

    // Only handle list endpoint (no ID in path) - must have either end of URL or query params after /organizations
    const isListEndpoint = url.match(/\/admin\/organizations(\?|$)/);

    if (route.request().method() === 'GET' && isListEndpoint) {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          data: MOCK_ORGANIZATIONS,
          pagination: {
            total: MOCK_ORGANIZATIONS.length,
            page: 1,
            page_size: 50,
            total_pages: 1,
            has_next: false,
            has_prev: false,
          },
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock sessions endpoints (same as regular user)
  await page.route(`${baseURL}/api/v1/sessions**`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          sessions: [MOCK_SESSION],
        }),
      });
    } else {
      await route.continue();
    }
  });

  await page.route(`${baseURL}/api/v1/sessions/*`, async (route: Route) => {
    if (route.request().method() === 'DELETE') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          message: 'Session revoked successfully',
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/stats - Get dashboard statistics with chart data
  await page.route(`${baseURL}/api/v1/admin/stats`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      // Generate user growth data for last 30 days
      const userGrowth = [];
      const today = new Date();
      for (let i = 29; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(date.getDate() - i);
        userGrowth.push({
          date: date.toISOString().split('T')[0],
          total_users: 50 + Math.floor((29 - i) * 1.5),
          active_users: Math.floor((50 + (29 - i) * 1.5) * 0.8),
        });
      }

      // Generate registration activity for last 14 days
      const registrationActivity = [];
      for (let i = 13; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(date.getDate() - i);
        registrationActivity.push({
          date: date.toISOString().split('T')[0],
          count: Math.floor(Math.random() * 5) + 1,
        });
      }

      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          user_growth: userGrowth,
          registration_activity: registrationActivity,
          organization_distribution: [
            { name: 'Acme Corporation', value: 12 },
            { name: 'Tech Innovators', value: 8 },
            { name: 'Global Solutions Inc', value: 25 },
            { name: 'Startup Ventures', value: 5 },
            { name: 'Inactive Corp', value: 3 },
          ],
          user_status: [
            { name: 'Active', value: 89 },
            { name: 'Inactive', value: 11 },
          ],
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/organizations/:id - Get single organization
  await page.route(`${baseURL}/api/v1/admin/organizations/*`, async (route: Route) => {
    const url = route.request().url();

    // Only handle single org endpoint (has ID but no /members suffix)
    const isSingleOrgEndpoint = url.match(/\/admin\/organizations\/[0-9a-f-]+\/?$/i);

    if (route.request().method() === 'GET' && isSingleOrgEndpoint) {
      // Extract org ID from URL
      const orgId = url.match(/organizations\/([^/]+)/)?.[1]?.replace(/\/$/, ''); // Remove trailing slash if any
      const org = MOCK_ORGANIZATIONS.find((o) => o.id === orgId) || MOCK_ORGANIZATIONS[0];

      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify(org),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/organizations/:id/members - Get organization members
  await page.route(`${baseURL}/api/v1/admin/organizations/*/members*`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          data: [],
          pagination: {
            total: 0,
            page: 1,
            page_size: 20,
            total_pages: 1,
            has_next: false,
            has_prev: false,
          },
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/admin/sessions - Get all sessions (for stats calculation)
  await page.route(`${baseURL}/api/v1/admin/sessions*`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          data: [MOCK_SESSION],
          pagination: {
            total: 45, // Total sessions for stats
            page: 1,
            page_size: 100,
            total_pages: 1,
            has_next: false,
            has_prev: false,
          },
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/auth/logout - Logout endpoint
  await page.route(`${baseURL}/api/v1/auth/logout`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ message: 'Logged out successfully' }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/admin/users - Create user
  await page.route(`${baseURL}/api/v1/admin/users`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      const postData = route.request().postDataJSON();
      await route.fulfill({
        status: 201,
        contentType: 'application/json',
        body: JSON.stringify({
          id: '00000000-0000-0000-0000-000000000099',
          email: postData.email,
          first_name: postData.first_name,
          last_name: postData.last_name || '',
          is_active: postData.is_active ?? true,
          is_superuser: postData.is_superuser ?? false,
          created_at: new Date().toISOString(),
          updated_at: new Date().toISOString(),
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock PATCH /api/v1/admin/users/:id - Update user
  await page.route(`${baseURL}/api/v1/admin/users/*`, async (route: Route) => {
    const url = route.request().url();
    const isUserEndpoint = url.match(/\/admin\/users\/[0-9a-f-]+\/?$/i);

    if (route.request().method() === 'PATCH' && isUserEndpoint) {
      const postData = route.request().postDataJSON();
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          ...MOCK_USER,
          ...postData,
          updated_at: new Date().toISOString(),
        }),
      });
    } else if (route.request().method() === 'DELETE' && isUserEndpoint) {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ message: 'User deleted successfully' }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/admin/users/bulk-action - Bulk operations
  await page.route(`${baseURL}/api/v1/admin/users/bulk-action`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      const postData = route.request().postDataJSON();
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          message: `Successfully ${postData.action}d ${postData.user_ids?.length || 0} users`,
          affected_count: postData.user_ids?.length || 0,
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock POST /api/v1/auth/change-password - Change password (for superuser)
  await page.route(`${baseURL}/api/v1/auth/change-password`, async (route: Route) => {
    if (route.request().method() === 'POST') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ message: 'Password changed successfully' }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/oauth/providers - Get available OAuth providers
  await page.route(`${baseURL}/api/v1/oauth/providers`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          enabled: true,
          providers: [
            { provider: 'google', name: 'Google' },
            { provider: 'github', name: 'GitHub' },
          ],
        }),
      });
    } else {
      await route.continue();
    }
  });

  // Mock GET /api/v1/oauth/authorize/:provider - Get OAuth authorization URL
  await page.route(`${baseURL}/api/v1/oauth/authorize/*`, async (route: Route) => {
    if (route.request().method() === 'GET') {
      const url = route.request().url();
      const provider = url.match(/authorize\/(\w+)/)?.[1] || 'google';
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          authorization_url: `https://mock-oauth.example.com/authorize?provider=${provider}`,
          state: 'mock-state-token',
        }),
      });
    } else {
      await route.continue();
    }
  });
}
