/**
 * Agent Conversation Management Steps
 *
 * Step definitions for Agent conversation management E2E tests
 * - Create new conversation
 * - Switch conversations
 * - Rename conversation
 * - Delete conversation
 * - Search conversations
 */
import { Given, Then, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';

import type { CustomWorld } from '../../support/world';

// ============================================
// Given Steps
// ============================================

Given('用户已有一个对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 创建一个对话...');

  // Send a message to create a conversation
  const chatInputs = this.page.locator('[data-testid="chat-input"]');
  const count = await chatInputs.count();

  let chatInputContainer = chatInputs.first();
  for (let i = 0; i < count; i++) {
    const elem = chatInputs.nth(i);
    const box = await elem.boundingBox();
    if (box && box.width > 0 && box.height > 0) {
      chatInputContainer = elem;
      break;
    }
  }

  await chatInputContainer.click();
  await this.page.waitForTimeout(300);
  await this.page.keyboard.type('hello', { delay: 30 });
  await this.page.keyboard.press('Enter');

  // Wait for response
  await this.page.waitForTimeout(2000);

  // Store the current conversation title for later reference
  const topicItems = this.page.locator('.ant-menu-item, [class*="NavItem"]');
  const topicCount = await topicItems.count();
  console.log(`   📍 Found ${topicCount} topic items after creating conversation`);

  console.log('   ✅ 已创建一个对话');
});

Given('用户有多个对话历史', async function (this: CustomWorld) {
  console.log('   📍 Step: 创建多个对话...');

  // Create first conversation
  const chatInputs = this.page.locator('[data-testid="chat-input"]');
  let chatInputContainer = chatInputs.first();
  const count = await chatInputs.count();
  for (let i = 0; i < count; i++) {
    const elem = chatInputs.nth(i);
    const box = await elem.boundingBox();
    if (box && box.width > 0 && box.height > 0) {
      chatInputContainer = elem;
      break;
    }
  }

  // First conversation - use "测试" content for search test
  await chatInputContainer.click();
  await this.page.waitForTimeout(300);
  await this.page.keyboard.type('测试对话内容', { delay: 30 });
  await this.page.keyboard.press('Enter');
  await this.page.waitForTimeout(2000);

  // Store first conversation reference
  this.testContext.firstConversation = 'first';

  // Create new topic and second conversation
  console.log('   📍 Creating second conversation...');
  const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');
  if ((await addTopicButton.count()) > 0) {
    await addTopicButton.first().click();
    await this.page.waitForTimeout(1000);

    // Send message in second conversation - different content
    await chatInputContainer.click();
    await this.page.waitForTimeout(300);
    await this.page.keyboard.type('hello world', { delay: 30 });
    await this.page.keyboard.press('Enter');
    await this.page.waitForTimeout(2000);
  }

  console.log('   ✅ 已创建多个对话');
});

// ============================================
// When Steps
// ============================================

When('用户点击新建对话按钮', async function (this: CustomWorld) {
  console.log('   📍 Step: 点击新建对话按钮...');

  // The add topic button uses MessageSquarePlusIcon from lucide-react
  const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');

  if ((await addTopicButton.count()) > 0) {
    await addTopicButton.first().click();
    console.log('   ✅ 已点击新建对话按钮');
  } else {
    // Fallback: look for button with "新建" or "add" in title
    const addButton = this.page.locator('button[title*="新建"], button[title*="add"]');
    if ((await addButton.count()) > 0) {
      await addButton.first().click();
      console.log('   ✅ 已点击新建对话按钮 (fallback)');
    } else {
      throw new Error('New topic button not found');
    }
  }

  await this.page.waitForTimeout(500);
});

When('用户点击另一个对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 点击另一个对话...');

  // Check if we're on the home page (has Recent Topics section)
  const recentTopicsSection = this.page.locator('text=Recent Topics');
  const isOnHomePage = (await recentTopicsSection.count()) > 0;
  console.log(`   📍 Is on home page: ${isOnHomePage}`);

  if (isOnHomePage) {
    // Click the second topic card in Recent Topics section
    // Cards are wrapped in Link components and contain "Hello! I am a mock AI" text from the mock
    const recentTopicCards = this.page.locator('a[href*="topic="]');
    const cardCount = await recentTopicCards.count();
    console.log(`   📍 Found ${cardCount} recent topic cards (by href)`);

    if (cardCount >= 2) {
      // Click the second card (different from current topic)
      await recentTopicCards.nth(1).click();
      console.log('   ✅ 已点击首页 Recent Topics 中的另一个对话');
      await this.page.waitForTimeout(2000);
      return;
    }

    // Fallback: try to find by text content
    const topicTextCards = this.page.locator('text=Hello! I am a mock AI');
    const textCardCount = await topicTextCards.count();
    console.log(`   📍 Found ${textCardCount} topic cards by text`);

    if (textCardCount >= 2) {
      await topicTextCards.nth(1).click();
      console.log('   ✅ 已点击首页 Recent Topics 中的另一个对话 (by text)');
      await this.page.waitForTimeout(2000);
      return;
    }
  }

  // Fallback: try to find topic items in the sidebar
  const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
  const topicCount = await sidebarTopics.count();
  console.log(`   📍 Found ${topicCount} topic items`);

  // Click the second topic (first one is current/active)
  if (topicCount >= 2) {
    await sidebarTopics.nth(1).click();
    console.log('   ✅ 已点击另一个对话');
  } else {
    throw new Error('Not enough topics to switch');
  }

  await this.page.waitForTimeout(500);
});

When('用户右键点击对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 右键点击对话...');

  const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
  const topicCount = await sidebarTopics.count();
  console.log(`   📍 Found ${topicCount} topic items`);

  if (topicCount > 0) {
    await sidebarTopics.first().click({ button: 'right' });
    console.log('   ✅ 已右键点击对话');
  } else {
    throw new Error('No topics found to right-click');
  }

  await this.page.waitForTimeout(500);
});

When('用户右键点击一个对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 右键点击一个对话...');

  const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
  const topicCount = await sidebarTopics.count();
  console.log(`   📍 Found ${topicCount} topic items`);

  // Store the topic text for later verification
  if (topicCount > 0) {
    const topicText = await sidebarTopics.first().textContent();
    this.testContext.deletedTopicTitle = topicText?.slice(0, 30);
    await sidebarTopics.first().click({ button: 'right' });
    console.log(`   ✅ 已右键点击对话: "${topicText?.slice(0, 30)}..."`);
  } else {
    throw new Error('No topics found to right-click');
  }

  await this.page.waitForTimeout(500);
});

When('用户选择重命名选项', async function (this: CustomWorld) {
  console.log('   📍 Step: 选择重命名选项...');

  // First, close any open context menu by clicking elsewhere
  await this.page.click('body', { position: { x: 500, y: 300 } });
  await this.page.waitForTimeout(300);

  // Instead of using right-click context menu, use the "..." dropdown menu
  // which appears when hovering over a topic item
  const topicItems = this.page.locator('[data-testid="topic-item"]');
  const topicCount = await topicItems.count();
  console.log(`   📍 Found ${topicCount} topic items`);

  if (topicCount > 0) {
    // Hover on the first topic to reveal the "..." action button
    const firstTopic = topicItems.first();
    await firstTopic.hover();
    console.log('   📍 Hovering on topic item...');
    await this.page.waitForTimeout(500);

    // The "..." button should now be visible INSIDE the topic item
    // Important: we must find the icon WITHIN the hovered topic, not the global one
    // The topic item has a specific structure with nav-item-actions
    const moreButtonInTopic = firstTopic.locator('svg.lucide-ellipsis, svg.lucide-more-horizontal');
    const moreButtonCount = await moreButtonInTopic.count();
    console.log(`   📍 Found ${moreButtonCount} more buttons inside topic`);

    if (moreButtonCount > 0) {
      // Click the "..." button to open dropdown menu
      await moreButtonInTopic.first().click();
      console.log('   📍 Clicked ... button inside topic');
      await this.page.waitForTimeout(500);
    } else {
      // Fallback: try to find it by looking at the actions container
      console.log('   📍 Trying alternative: looking for actions container...');

      // Debug: print the topic item HTML structure
      const topicHTML = await firstTopic.evaluate((el) => el.outerHTML.slice(0, 500));
      console.log(`   📍 Topic HTML: ${topicHTML}`);

      // The actions might be in a sibling or parent element
      // Try finding any ellipsis icon that's near the topic
      const allEllipsis = this.page.locator('svg.lucide-ellipsis');
      const ellipsisCount = await allEllipsis.count();
      console.log(`   📍 Total ellipsis icons on page: ${ellipsisCount}`);

      // Skip the first one (which is the global topic list menu)
      // and click the second one (which should be in the topic item)
      if (ellipsisCount > 1) {
        await allEllipsis.nth(1).click();
        console.log('   📍 Clicked second ellipsis icon');
        await this.page.waitForTimeout(500);
      }
    }
  }

  // Now find the rename option in the dropdown menu
  const renameOption = this.page.getByRole('menuitem', { exact: true, name: /^(Rename|重命名)$/ });

  await expect(renameOption).toBeVisible({ timeout: 5000 });
  console.log('   📍 Found rename menu item');

  // Click the rename option
  await renameOption.click();
  console.log('   📍 Clicked rename menu item');

  // Wait for the popover/input to appear
  await this.page.waitForTimeout(500);

  // Check if input appeared
  const inputCount = await this.page.locator('input').count();
  console.log(`   📍 After click: ${inputCount} inputs on page`);

  console.log('   ✅ 已选择重命名选项');
});

When('用户输入新的对话名称 {string}', async function (this: CustomWorld, newName: string) {
  console.log(`   📍 Step: 输入新名称 "${newName}"...`);

  // Debug: check what's on the page
  const debugInfo = await this.page.evaluate(() => {
    const allInputs = document.querySelectorAll('input');
    const allPopovers = document.querySelectorAll('[class*="popover"], .ant-popover');
    const focusedElement = document.activeElement;
    return {
      focusedClass: focusedElement?.className,
      focusedTag: focusedElement?.tagName,
      inputCount: allInputs.length,
      inputTags: Array.from(allInputs).map((i) => ({
        className: i.className,
        placeholder: i.placeholder,
        type: i.type,
        visible: i.offsetParent !== null,
      })),
      popoverCount: allPopovers.length,
    };
  });
  console.log('   📍 Debug info:', JSON.stringify(debugInfo, null, 2));

  // Wait a short moment for the popover to render
  await this.page.waitForTimeout(300);

  // The rename UI can render as a dialog/modal in CI, not only as a popover.
  const renameInputSelectors = [
    '[role="dialog"] input[type="text"]',
    '.ant-modal input[type="text"]',
    '[data-testid="editing-popover"] input',
    '.ant-popover-inner input',
    '.ant-popover-content input',
    '.ant-popover input',
    'input[type="text"]:visible',
  ];

  let renameInput = null;

  // Wait for any rename input to appear
  for (const selector of renameInputSelectors) {
    try {
      const locator = this.page.locator(selector).first();
      await locator.waitFor({ state: 'visible', timeout: 2000 });
      renameInput = locator;
      console.log(`   📍 Found input with selector: ${selector}`);
      break;
    } catch {
      // Try next selector
    }
  }

  if (!renameInput) {
    // Fallback: find any visible input that's not the search or chat input
    console.log('   📍 Trying fallback: finding any visible input...');
    const allInputs = this.page.locator('input:visible');
    const count = await allInputs.count();
    console.log(`   📍 Found ${count} visible inputs`);

    for (let i = 0; i < count; i++) {
      const input = allInputs.nth(i);
      const placeholder = await input.getAttribute('placeholder').catch(() => '');
      const testId = await input.getAttribute('data-testid').catch(() => '');

      // Skip search inputs and chat inputs
      if (placeholder?.includes('Search') || placeholder?.includes('搜索')) continue;
      if (testId === 'chat-input') continue;

      // Prefer inputs rendered inside rename containers.
      const isInRenameContainer = await input.evaluate((el) => {
        return (
          el.closest('[role="dialog"]') !== null ||
          el.closest('.ant-modal') !== null ||
          el.closest('.ant-popover') !== null ||
          el.closest('[class*="popover"]') !== null
        );
      });

      if (isInRenameContainer || count === 1) {
        renameInput = input;
        console.log(`   📍 Found candidate input at index ${i}`);
        break;
      }
    }
  }

  if (renameInput) {
    // Clear and fill the input
    await renameInput.click();
    await renameInput.clear();
    await renameInput.fill(newName);
    console.log(`   📍 Filled input with "${newName}"`);

    const saveButton = this.page
      .locator('[role="dialog"]')
      .getByRole('button', { exact: true, name: /^(Save|保存)$/ })
      .first();

    try {
      await saveButton.waitFor({ state: 'visible', timeout: 1000 });
      await saveButton.click();
      console.log('   📍 Clicked save button');
    } catch {
      // Popover-based rename UIs still confirm with Enter.
      await renameInput.press('Enter');
      console.log('   📍 Confirmed rename with Enter');
    }

    console.log(`   ✅ 已输入新名称 "${newName}"`);
  } else {
    // Last resort: the input should have autoFocus, so keyboard should work
    console.log('   ⚠️ Could not find rename input element, using keyboard fallback...');
    // Select all and replace
    await this.page.keyboard.press('Meta+A');
    await this.page.waitForTimeout(50);
    await this.page.keyboard.type(newName, { delay: 20 });
    await this.page.keyboard.press('Enter');
    console.log(`   ✅ 已通过键盘输入新名称 "${newName}"`);
  }

  // Wait for the rename to be saved
  await this.page.waitForTimeout(1000);
});

When('用户选择删除选项', async function (this: CustomWorld) {
  console.log('   📍 Step: 选择删除选项...');

  // The context menu should be visible with "delete" option
  // Support both English and Chinese
  const deleteOption = this.page.getByRole('menuitem', { exact: true, name: /^(Delete|删除)$/ });

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

  console.log('   ✅ 已选择删除选项');
  await this.page.waitForTimeout(300);
});

When('用户确认删除', async function (this: CustomWorld) {
  console.log('   📍 Step: 确认删除...');

  const confirmButton = this.page
    .getByRole('dialog')
    .getByRole('button', { name: /^(ok|delete|删除|确认|确定)$/i });

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

  console.log('   ✅ 已确认删除');
  await this.page.waitForTimeout(500);
});

When('用户在搜索框中输入 {string}', async function (this: CustomWorld, searchText: string) {
  console.log(`   📍 Step: 在搜索框中输入 "${searchText}"...`);

  // Find the search input in the sidebar
  // Support both English and Chinese placeholders
  const searchInput = this.page.locator(
    'input[placeholder*="Search"], input[placeholder*="搜索"], [data-testid="search-input"]',
  );

  if ((await searchInput.count()) > 0) {
    await searchInput.first().click();
    await searchInput.first().fill(searchText);
  } else {
    // Fallback: click on search icon to reveal search input
    const searchIcon = this.page.locator('svg.lucide-search').locator('..');
    if ((await searchIcon.count()) > 0) {
      await searchIcon.first().click();
      await this.page.waitForTimeout(300);
      // Now find the input
      const input = this.page.locator('input[type="text"]').last();
      await input.fill(searchText);
    }
  }

  console.log(`   ✅ 已输入搜索内容 "${searchText}"`);
  await this.page.waitForTimeout(500);
});

// ============================================
// Then Steps
// ============================================

Then('应该创建一个新的空白对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证新对话已创建...');

  // The chat area should be empty or show welcome message
  // Check that there are no user/assistant messages
  const userMessages = this.page.locator('[data-role="user"]');
  const assistantMessages = this.page.locator('[data-role="assistant"]');

  const userCount = await userMessages.count();
  const assistantCount = await assistantMessages.count();

  console.log(`   📍 用户消息数量: ${userCount}, 助手消息数量: ${assistantCount}`);

  // New conversation should have no messages
  expect(userCount).toBe(0);
  expect(assistantCount).toBe(0);

  console.log('   ✅ 新对话已创建');
});

Then('页面应该显示欢迎界面', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证页面显示欢迎界面...');

  // Wait for the page to update
  await this.page.waitForTimeout(500);

  // New conversation typically shows a welcome/empty state
  // Check for visible chat input (there may be 2 - desktop and mobile, find the visible one)
  const chatInputs = this.page.locator('[data-testid="chat-input"]');
  const count = await chatInputs.count();

  let foundVisible = false;
  for (let i = 0; i < count; i++) {
    const elem = chatInputs.nth(i);
    const box = await elem.boundingBox();
    if (box && box.width > 0 && box.height > 0) {
      foundVisible = true;
      console.log(`   📍 Found visible chat-input at index ${i}`);
      break;
    }
  }

  // Just verify the page is loaded properly by checking URL or any content
  if (!foundVisible) {
    // Fallback: just verify we're still on the chat page
    const currentUrl = this.page.url();
    expect(currentUrl).toContain('/chat');
    console.log('   📍 Fallback: verified we are on chat page');
  }

  console.log('   ✅ 欢迎界面已显示');
});

Then('应该切换到该对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证已切换对话...');

  // The URL or active state should change
  // For now, just verify the page is responsive
  await this.page.waitForTimeout(500);

  console.log('   ✅ 已切换到该对话');
});

Then('显示该对话的历史消息', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证显示历史消息...');

  // Wait for the loading to finish - the messages need time to load after switching topics
  console.log('   📍 等待消息加载...');
  await this.page.waitForTimeout(2000);

  // Wait for the message wrapper to appear (ChatItem component uses message-wrapper class)
  const messageSelector = '.message-wrapper';
  try {
    await this.page.waitForSelector(messageSelector, { timeout: 10_000 });
  } catch {
    console.log('   ⚠️ 等待消息选择器超时，尝试备用选择器...');
  }

  // There should be messages in the chat area
  const messages = this.page.locator(messageSelector);
  const messageCount = await messages.count();

  console.log(`   📍 找到 ${messageCount} 条消息`);

  // At least some messages should be visible
  expect(messageCount).toBeGreaterThan(0);

  console.log('   ✅ 历史消息已显示');
});

Then('对话名称应该更新为 {string}', async function (this: CustomWorld, expectedName: string) {
  console.log(`   📍 Step: 验证对话名称为 "${expectedName}"...`);

  // Wait for the rename to take effect
  await this.page.waitForTimeout(1000);

  // Find the topic with the new name by text content
  // Topics are in the sidebar, look for text directly
  // Use .first() since the name might appear in multiple places (sidebar + favorites section)
  const renamedTopic = this.page.getByText(expectedName, { exact: true }).first();

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

  console.log(`   ✅ 对话名称已更新为 "${expectedName}"`);
});

Then('该对话应该被删除', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证对话已删除...');

  // Wait for deletion to take effect
  await this.page.waitForTimeout(500);

  console.log('   ✅ 对话已删除');
});

Then('对话列表中不再显示该对话', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证对话列表中不再显示该对话...');

  // Wait for UI to update
  await this.page.waitForTimeout(500);

  // The deleted topic should not be in the list
  if (this.testContext.deletedTopicTitle) {
    const deletedTopic = this.page.locator(
      `[class*="NavItem"]:has-text("${this.testContext.deletedTopicTitle}")`,
    );
    const count = await deletedTopic.count();
    expect(count).toBe(0);
    console.log(`   ✅ 对话 "${this.testContext.deletedTopicTitle}" 已从列表中移除`);
  } else {
    console.log('   ✅ 对话已从列表中移除');
  }
});

Then('应该显示包含 {string} 的对话', async function (this: CustomWorld, searchText: string) {
  console.log(`   📍 Step: 验证搜索结果包含 "${searchText}"...`);

  // Wait for search results to load (search opens a modal dialog)
  await this.page.waitForTimeout(2000);

  // Search results appear in a modal/dialog, not in sidebar
  // Look for the search modal and check for matching results
  const searchModal = this.page.locator('.ant-modal, [role="dialog"]');
  const hasModal = (await searchModal.count()) > 0;
  console.log(`   📍 搜索模态框: ${hasModal}`);

  // Find matching items in the search results (either in modal or in sidebar if filtered)
  const matchingInModal = searchModal.getByText(searchText);
  const matchingInPage = this.page.getByText(searchText);

  const modalMatchCount = await matchingInModal.count();
  const pageMatchCount = await matchingInPage.count();

  console.log(`   📍 模态框中找到 ${modalMatchCount} 个匹配, 页面中找到 ${pageMatchCount} 个匹配`);

  // At least one match should be found (either in search input or results)
  expect(modalMatchCount + pageMatchCount).toBeGreaterThan(0);

  console.log(`   ✅ 搜索结果显示包含 "${searchText}" 的对话`);
});

Then('不相关的对话应该被过滤', async function (this: CustomWorld) {
  console.log('   📍 Step: 验证不相关对话已被过滤...');

  // This would require checking that non-matching topics are hidden
  // For now, just verify the search is active
  await this.page.waitForTimeout(300);

  console.log('   ✅ 不相关对话已被过滤');
});
