import { test, expect } from '@playwright/test';
import { loginToJamUI, createAndJoinSession } from '../utils/test-helpers';

test.describe('Receive Message', () => {
  test.beforeEach(async ({ page }) => {
    await loginToJamUI(page);
    await createAndJoinSession(page);

    // Open chat window
    const chatButton = page.locator('img[alt="Chat"]');
    await chatButton.click();
  });

  test('displays message received via WebSocket', async ({ page, context }) => {
    const popupPromise = context.waitForEvent('page');
    const popup = await popupPromise;
    await popup.waitForLoadState('domcontentloaded');

    // Simulate receiving message via WebSocket (dispatch Redux action)
    await page.evaluate(() => {
      const store = (window as any).__REDUX_STORE__;

      // Simulate WebSocket message
      store.dispatch({
        type: 'sessionChat/addMessageFromWebSocket',
        payload: {
          id: 'test-msg-123',
          senderId: 'other-user-id',
          senderName: 'Test User',
          message: 'Hello from WebSocket!',
          createdAt: new Date().toISOString(),
          channel: 'test-session-id'
        }
      });
    });

    // Wait for message to appear in popup
    await popup.waitForTimeout(500);
    const message = popup.locator('text=Hello from WebSocket!');
    await expect(message).toBeVisible();

    // Verify sender name displayed
    const sender = popup.locator('text=Test User');
    await expect(sender).toBeVisible();
  });

  test('does not duplicate sent message when received via WebSocket', async ({ page, context }) => {
    const popupPromise = context.waitForEvent('page');
    const popup = await popupPromise;
    await popup.waitForLoadState('domcontentloaded');

    // Send message
    const textarea = popup.locator('textarea[placeholder*="Type a message"]');
    await textarea.fill('No duplicate test');

    const sendButton = popup.locator('button:has-text("Send")');
    await sendButton.click();

    // Wait for optimistic update
    await popup.waitForTimeout(300);

    // Simulate receiving same message via WebSocket (with same msg_id)
    await page.evaluate(() => {
      const store = (window as any).__REDUX_STORE__;
      const state = store.getState();

      // Get the message that was just sent (will have msg_id from server)
      const messages = state.sessionChat.messagesByChannel['test-session-id'] || [];
      const lastMessage = messages[messages.length - 1];

      // Try to add again via WebSocket (should be deduplicated)
      if (lastMessage) {
        store.dispatch({
          type: 'sessionChat/addMessageFromWebSocket',
          payload: lastMessage
        });
      }
    });

    await popup.waitForTimeout(300);

    // Should only have ONE instance of the message
    const messages = popup.locator('text=No duplicate test');
    expect(await messages.count()).toBe(1);
  });

  test('auto-scrolls to bottom when new message received', async ({ page, context }) => {
    const popupPromise = context.waitForEvent('page');
    const popup = await popupPromise;
    await popup.waitForLoadState('domcontentloaded');

    // Add multiple messages to enable scrolling
    for (let i = 1; i <= 10; i++) {
      await page.evaluate((num) => {
        const store = (window as any).__REDUX_STORE__;
        store.dispatch({
          type: 'sessionChat/addMessageFromWebSocket',
          payload: {
            id: `msg-${num}`,
            senderId: 'user-id',
            senderName: 'Test User',
            message: `Message ${num}`,
            createdAt: new Date().toISOString(),
            channel: 'test-session-id'
          }
        });
      }, i);

      await popup.waitForTimeout(100);
    }

    // Last message should be visible (auto-scrolled)
    const lastMessage = popup.locator('text=Message 10');
    await expect(lastMessage).toBeVisible();
  });

  test('increments unread badge when message received and window closed', async ({ page, context }) => {
    // Open then close chat window
    const chatButton = page.locator('img[alt="Chat"]');
    await chatButton.click();

    const popupPromise = context.waitForEvent('page');
    const popup = await popupPromise;
    await popup.waitForLoadState('domcontentloaded');

    // Close window
    const closeButton = popup.locator('button[aria-label="Close chat"]');
    await closeButton.click();
    await page.waitForTimeout(500);

    // Simulate receiving message while window closed
    await page.evaluate(() => {
      const store = (window as any).__REDUX_STORE__;
      store.dispatch({
        type: 'sessionChat/addMessageFromWebSocket',
        payload: {
          id: 'msg-closed-window',
          senderId: 'other-user',
          senderName: 'Test User',
          message: 'Message while closed',
          createdAt: new Date().toISOString(),
          channel: 'test-session-id'
        }
      });
    });

    await page.waitForTimeout(300);

    // Unread badge should show "1"
    const badge = page.locator('div:has-text("1")').filter({ hasText: /^1$/ });
    await expect(badge).toBeVisible();
  });
});
