import { test, expect } from '@playwright/test';
import { setupMockApi, mockUsers, mockAuthToken, mockTasks, mockPosts, mockEvents } from './fixtures/mock-api.js';

// Helper function to login
async function login(page) {
  await page.route('**/api/auth/login', async route => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        success: true,
        token: mockAuthToken,
        user: mockUsers.testUser
      })
    });
  });

  await page.goto('http://localhost:3000/login');
  await page.fill('[data-testid="email-input"]', 'test@example.com');
  await page.fill('[data-testid="password-input"]', 'password123');
  await page.click('[data-testid="login-submit-btn"]');
  await page.waitForURL('**/map', { timeout: 5000 }).catch(() => null);
}

test.describe('Task Management', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('user can view task list', async ({ page }) => {
    await login(page);
    
    // Navigate to tasks
    await page.goto('http://localhost:3000/tasks');
    
    // Wait for tasks to load
    await page.waitForSelector('[data-testid="task-list-container"]', { timeout: 5000 }).catch(() => null);
    
    // Check if task list is visible
    const taskList = page.locator('[data-testid="task-list-container"]');
    expect(taskList).toBeDefined();
  });

  test('user can complete a task', async ({ page }) => {
    await login(page);
    
    // Navigate to tasks
    await page.goto('http://localhost:3000/tasks');
    
    // Mock task completion endpoint
    await page.route('**/api/tasks/**', async route => {
      if (route.request().method() === 'PUT') {
        await route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({ ...mockTasks[0], status: 'completed' })
        });
      } else {
        await route.abort();
      }
    });
    
    // Wait for tasks to load
    await page.waitForTimeout(1000);
    
    // Try to find and click a complete button
    const completeButtons = page.locator('[data-testid^="complete-task-btn-"]');
    const count = await completeButtons.count();
    
    if (count > 0) {
      await completeButtons.first().click();
      await page.waitForTimeout(500);
    }
  });

  test('user can filter tasks by status', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/tasks');
    
    // Check if task list container is present
    const taskList = page.locator('[data-testid="task-list-container"]');
    expect(taskList).toBeDefined();
  });

  test('user can search tasks', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/tasks');
    
    // Check for task list
    const taskList = page.locator('[data-testid="tasks-list"]');
    if (await taskList.isVisible()) {
      expect(taskList).toBeDefined();
    }
  });
});

test.describe('Social Feed', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('user can view social feed posts', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/feed');
    
    // Wait for feed to load
    await page.waitForSelector('[data-testid="social-feed-container"]', { timeout: 5000 }).catch(() => null);
    
    const feedContainer = page.locator('[data-testid="social-feed-container"]');
    expect(feedContainer).toBeDefined();
  });

  test('user can create a post', async ({ page }) => {
    await login(page);
    
    // Mock post creation
    await page.route('**/api/posts', async route => {
      if (route.request().method() === 'POST') {
        const postData = await route.request().postDataJSON();
        await route.fulfill({
          status: 201,
          contentType: 'application/json',
          body: JSON.stringify({
            _id: '507f1f77bcf86cd799439099',
            content: postData.content,
            user: mockUsers.testUser,
            likes: [],
            comments: [],
            createdAt: new Date().toISOString()
          })
        });
      } else {
        await route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify(mockPosts)
        });
      }
    });

    await page.goto('http://localhost:3000/feed');
    
    // Wait for feed to load
    await page.waitForSelector('[data-testid="social-feed-container"]', { timeout: 5000 }).catch(() => null);
    
    // Find and fill the post textarea
    const textarea = page.locator('[data-testid="post-content-textarea"]');
    if (await textarea.isVisible()) {
      await textarea.fill('This is a test post!');
      
      // Click the post button
      const postBtn = page.locator('[data-testid="create-post-btn"]');
      await postBtn.click();
      
      // Wait for post to be created
      await page.waitForTimeout(1000);
    }
  });

  test('user can like a post', async ({ page }) => {
    await login(page);
    
    // Mock like endpoint
    await page.route('**/api/posts/like/**', async route => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify([mockUsers.testUser])
      });
    });

    await page.goto('http://localhost:3000/feed');
    
    // Wait for posts to load
    await page.waitForTimeout(1000);
    
    // Try to find and click a like button
    const likeButtons = page.locator('[data-testid^="like-btn-"]');
    const count = await likeButtons.count();
    
    if (count > 0) {
      await likeButtons.first().click();
      await page.waitForTimeout(500);
    }
  });

  test('user can view post comments', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/feed');
    
    // Wait for posts to load
    await page.waitForTimeout(1000);
    
    // Check if posts are visible
    const posts = page.locator('[data-testid^="post-item-"]');
    const postCount = await posts.count();
    expect(postCount).toBeGreaterThanOrEqual(0);
  });
});

test.describe('Events', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('user can view events', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/events');
    
    // Wait for events to load
    await page.waitForSelector('[data-testid="events-container"]', { timeout: 5000 }).catch(() => null);
    
    const eventsContainer = page.locator('[data-testid="events-container"]');
    expect(eventsContainer).toBeDefined();
  });

  test('user can join an event', async ({ page }) => {
    await login(page);
    
    // Mock RSVP endpoint
    await page.route('**/api/events/rsvp/**', async route => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify([mockUsers.testUser, mockUsers.premiumUser])
      });
    });

    await page.goto('http://localhost:3000/events');
    
    // Wait for events to load
    await page.waitForTimeout(1000);
    
    // Try to find and click an RSVP button
    const rsvpButtons = page.locator('[data-testid^="rsvp-btn-"]');
    const count = await rsvpButtons.count();
    
    if (count > 0) {
      await rsvpButtons.first().click();
      await page.waitForTimeout(500);
    }
  });

  test('user can filter events by status', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/events');
    
    // Check for events container
    const eventsContainer = page.locator('[data-testid="events-container"]');
    expect(eventsContainer).toBeDefined();
  });

  test('user can view event details', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/events');
    
    // Wait for events to load
    await page.waitForTimeout(1000);
    
    // Check for event cards
    const eventCards = page.locator('[data-testid^="event-card-"]');
    const cardCount = await eventCards.count();
    expect(cardCount).toBeGreaterThanOrEqual(0);
  });
});

test.describe('Profile', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('user can view their profile', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/profile');
    
    // Wait for profile to load
    await page.waitForSelector('[data-testid="profile-container"]', { timeout: 5000 }).catch(() => null);
    
    const profileContainer = page.locator('[data-testid="profile-container"]');
    expect(profileContainer).toBeDefined();
  });

  test('profile displays user information correctly', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/profile');
    
    // Wait for profile to load
    await page.waitForTimeout(1000);
    
    // Check for profile info card
    const infoCard = page.locator('[data-testid="profile-info-card"]');
    if (await infoCard.isVisible()) {
      expect(infoCard).toBeDefined();
    }
  });

  test('profile displays adopted streets', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/profile');
    
    // Wait for profile to load
    await page.waitForTimeout(1000);
    
    // Check for adopted streets card
    const streetsCard = page.locator('[data-testid="adopted-streets-card"]');
    if (await streetsCard.isVisible()) {
      expect(streetsCard).toBeDefined();
    }
  });

  test('profile displays badges earned', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/profile');
    
    // Wait for profile to load
    await page.waitForTimeout(1000);
    
    // Check for badges card
    const badgesCard = page.locator('[data-testid="badges-card"]');
    if (await badgesCard.isVisible()) {
      expect(badgesCard).toBeDefined();
    }
  });

  test('profile displays user statistics', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/profile');
    
    // Wait for profile to load
    await page.waitForTimeout(1000);
    
    // Check for statistics card
    const statsCard = page.locator('[data-testid="statistics-card"]');
    if (await statsCard.isVisible()) {
      expect(statsCard).toBeDefined();
    }
  });
});

test.describe('Premium Features', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('premium subscription page loads', async ({ page }) => {
    await page.goto('http://localhost:3000/premium');
    
    // Wait for page to load
    await page.waitForLoadState('networkidle');
    
    // Check if page content is present
    const content = await page.content();
    expect(content).toBeDefined();
  });

  test('user can view premium features', async ({ page }) => {
    await page.goto('http://localhost:3000/premium');
    
    // Check if page loaded
    const content = await page.content();
    expect(content).toBeDefined();
    expect(content.length).toBeGreaterThan(0);
  });
});

test.describe('Leaderboard', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('user can view leaderboard', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/leaderboard');
    
    // Wait for leaderboard to load
    await page.waitForLoadState('networkidle');
    
    // Check if leaderboard is displayed
    const content = await page.content();
    expect(content).toBeDefined();
  });

  test('leaderboard displays rankings correctly', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/leaderboard');
    
    // Wait for leaderboard to load
    await page.waitForLoadState('networkidle');
    
    // Check if rankings are visible
    const content = await page.content();
    expect(content).toBeDefined();
  });

  test('user can filter leaderboard by timeframe', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/leaderboard');
    
    // Wait for leaderboard to load
    await page.waitForLoadState('networkidle');
    
    // Check if leaderboard content exists
    const content = await page.content();
    expect(content).toBeDefined();
  });
});

test.describe('Map View', () => {
  test.beforeEach(async ({ page }) => {
    await setupMockApi(page);
  });

  test('map loads with streets', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/map');
    
    // Wait for map to load
    await page.waitForLoadState('networkidle');
    
    // Map should be visible
    const content = await page.content();
    expect(content).toBeDefined();
  });

  test('user can interact with map', async ({ page }) => {
    await login(page);
    
    await page.goto('http://localhost:3000/map');
    
    // Wait for map to load
    await page.waitForLoadState('networkidle');
    
    // Map should exist
    const content = await page.content();
    expect(content).toBeDefined();
  });
});
