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

const BASE_URL = 'http://localhost:5173'; // Assuming Vite's default dev server URL

// Function to generate a unique email for signup
const generateUniqueEmail = () => `testuser_${Date.now()}@example.com`;

let userEmail = ''; // Will be set by signup test and used by login test
const userPassword = 'Password123!';

test.describe.configure({ mode: 'serial' }); // Run tests in this file serially

test.beforeAll(async () => {
  userEmail = generateUniqueEmail(); // Generate unique email once for the suite
});

test('1. Successful User Signup', async ({ page }) => {
  await page.goto(`${BASE_URL}/auth/signup`);

  // Fill out the signup form
  await page.locator('input#name').fill('Test User');
  await page.locator('input#email').fill(userEmail);
  await page.locator('input#password').fill(userPassword);
  await page.locator('input#confirmPassword').fill(userPassword);

  // Submit the form
  await page.locator('form button[type="submit"]:has-text("Sign Up")').click();

  // Verify redirection to the login page
  await page.waitForURL(`${BASE_URL}/auth/login`);
  await expect(page).toHaveURL(`${BASE_URL}/auth/login`);

  // Optionally, verify a success message if one exists on the login page after signup
  // For example, if a query param or a notification store message is used.
  // This example assumes direct redirection without a specific persistent message on login page itself.
  // A common pattern is a toast notification, which might be harder to assert reliably here without more specific selectors.
  // For now, redirection is the primary assertion.
  // We can also check if the email field on login page is pre-filled if that's a feature.
  // await expect(page.locator('input#email')).toHaveValue(userEmail); // Uncomment if this is expected
});

test('2. Successful Login', async ({ page }) => {
  await page.goto(`${BASE_URL}/auth/login`);

  // Fill out the login form with credentials from the signup test
  await page.locator('input#email').fill(userEmail);
  await page.locator('input#password').fill(userPassword);

  // Submit the form
  await page.locator('form button[type="submit"]:has-text("Login")').click();

  // Verify redirection to a main application page (e.g., /chores or /groups or /)
  // Using a regex to be flexible about the exact landing page after login.
  await page.waitForURL(new RegExp(`${BASE_URL}/(chores|groups|dashboard)?/?$`));
  // More specific check if you know the exact page:
  // await page.waitForURL(`${BASE_URL}/chores`);
  // await expect(page).toHaveURL(`${BASE_URL}/chores`);

  // Assert the presence of an element indicating successful login.
  // This could be a logout button, user's name, etc.
  // I need to find what the actual "logged in" indicator is.
  // Let's assume there's a layout component for authenticated routes that includes a common header or nav.
  // For now, let's look for a button that might be "Logout" or "Account" or "Profile".
  // Or a common page title on the dashboard/chores page.
  // Example: Check for a common header/title on a likely landing page.
  // If the /chores page has an H1 "All Chores", we can check for that.
  const mainHeading = page.locator('h1'); // A general h1
  await expect(mainHeading.first()).toBeVisible({ timeout: 10000 }); // Wait for page to load
  // If it's /chores, the heading is "All Chores"
  // If it's /groups, the heading is "Groups"
  // If it's /dashboard, it might be "Dashboard"
  // This assertion needs to be tailored to the actual application.
  // For now, just ensuring some H1 is visible on the new page is a basic check.

  // A more reliable check would be a specific logout button, if its selector is known.
  // await expect(page.locator('nav button:has-text("Logout")')).toBeVisible();
});

test('3. Successful Logout', async ({ page }) => {
  // First, ensure the user is logged in (or perform login steps)
  // This test depends on the previous login test having set cookies correctly.
  // If running this test standalone, you'd need to programmatically log in first.
  await page.goto(`${BASE_URL}/auth/login`);
  await page.locator('input#email').fill(userEmail);
  await page.locator('input#password').fill(userPassword);
  await page.locator('form button[type="submit"]:has-text("Login")').click();
  
  // Wait for navigation to a logged-in page (e.g., /chores)
  await page.waitForURL(new RegExp(`${BASE_URL}/(chores|groups|dashboard)?/?$`));
  await expect(page.locator('h1').first()).toBeVisible({ timeout: 10000 });


  // Find and click the logout button.
  // The logout button's selector needs to be determined by inspecting the actual application.
  // Common places: Navbar, User dropdown, Account page.
  // Let's try to find it on the AccountPage as a common location.
  // First navigate to account page, then logout.
  // This assumes a link/button to the account page is available.
  // Let's assume a common pattern for a navbar link to Account page.
  // If no global nav, we might need a more specific way to trigger logout.
  // For now, let's assume there is an Account page link and then a logout button there.
  // This is a placeholder and likely needs adjustment.

  // Attempt to find a logout button. This selector is a guess.
  // A better approach is to have a data-testid for logout button.
  // Let's first try to navigate to the account page assuming there's a link.
  // This part is highly dependent on the app's structure.
  // For now, I'll assume the ChoresPage might have a direct logout or an account link.
  // If AccountPage has a logout button:
  // await page.goto(`${BASE_URL}/account`);
  // const logoutButton = page.locator('button:has-text("Logout")'); // Generic

  // Given the current app structure, a logout button is not globally visible.
  // Let's assume the "Account Settings" page (AccountPage.vue) should have it.
  // However, AccountPage.vue itself doesn't show a logout button in its template.
  // The authStore.logout() method does router.push('/auth/login').
  // This implies that whatever button calls authStore.logout() would be the logout trigger.
  
  // Let's assume there is a navigation element that becomes visible after login,
  // which contains a link to the account page or a direct logout button.
  // This is a common pattern missing from the current file analysis.
  // For the E2E test to proceed, I'll need to make an assumption or the app needs a clear logout path.

  // Click the user menu button to reveal the dropdown
  await page.locator('.user-menu-button').click();

  // Wait for the dropdown menu to be visible (optional, but good practice if animations are present)
  await page.locator('.dropdown-menu').waitFor({ state: 'visible' });

  // Click the "Logout" link within the dropdown menu
  await page.locator('.dropdown-menu a:has-text("Logout")').click();


  // Verify redirection to the login page
  await page.waitForURL(`${BASE_URL}/auth/login`);
  await expect(page).toHaveURL(`${BASE_URL}/auth/login`);

  // Optionally, verify that elements indicating a logged-in state are gone.
  // For example, if a user menu was present, it should now be gone.
  // await expect(page.locator('#user-menu')).not.toBeVisible();
});

// To make login/logout tests more robust if run independently or if state between tests is an issue:
// - Consider using Playwright's global setup to create a user.
// - Or, use page.context().addCookies() and page.context().addInitScript() to set auth state programmatically
//   before tests that require a logged-in user, bypassing UI login for speed and reliability.
//   However, the task asks for testing the UI login flow.
// - The `test.describe.configure({ mode: 'serial' });` makes the tests run in order,
//   allowing the login test to use credentials from signup, and logout to use the session from login.
//   This is acceptable for a small suite like this.