import { TIMEOUTS } from '../../utils/timeouts';
import { test, expect } from '../../utils/test-setup';
import { UserType } from '@d8d/shared-types';

/**
 * 企业用户创建 E2E 测试
 *
 * 测试后台创建企业用户功能的正确性
 * 验证创建基本企业用户、完整信息企业用户、公司关联验证、表单验证等功能
 *
 * @see {@link ../pages/admin/user-management.page.ts} UserManagementPage
 */
test.describe('企业用户创建功能', () => {
  // 测试创建的公司名称，用于清理
  let testCompanyName: string;

  test.beforeEach(async ({ adminLoginPage, companyManagementPage, userManagementPage }) => {
    // 以管理员身份登录后台
    await adminLoginPage.goto();
    await adminLoginPage.login('admin', 'admin123');
    await adminLoginPage.expectLoginSuccess();

    // 创建测试公司（企业用户必须关联公司）
    const timestamp = Date.now();
    testCompanyName = `测试公司_${timestamp}`;
    await companyManagementPage.goto();
    await companyManagementPage.createCompany({
      companyName: testCompanyName,
    });

    // 验证公司创建成功
    const companyExists = await companyManagementPage.companyExists(testCompanyName);
    expect(companyExists).toBe(true);

    // 导航到用户管理页面
    await userManagementPage.goto();
  });

  test.afterEach(async ({ companyManagementPage }) => {
    // 清理测试数据（公司）
    await companyManagementPage.goto();
    await companyManagementPage.deleteCompany(testCompanyName);
  });

  test.describe('基本创建流程测试', () => {
    test('应该成功创建基本企业用户', async ({ userManagementPage }) => {
      // 生成唯一用户名
      const timestamp = Date.now();
      const username = `test_employer_${timestamp}`;

      // 创建企业用户（填写必填字段 + 选择公司）
      const result = await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: '测试企业用户',
        userType: UserType.EMPLOYER,
        // companyId 由 Page Object 通过公司名称自动处理，无需指定
      }, testCompanyName);

      // 验证 API 响应成功
      expect(result.responses).toBeDefined();
      expect(result.responses?.length).toBeGreaterThan(0);
      const createResponse = result.responses?.find(r => r.url.includes('/api/v1/users'));
      expect(createResponse?.ok).toBe(true);

      // 验证创建成功提示（可选，Toast 检测可能不稳定）
      // 如果能检测到 Toast，验证消息内容
      if (result.hasSuccess && result.successMessage) {
        expect(result.successMessage).toContain('成功');
      }
      // 最终验证：用户出现在列表中（这才是真正的成功证明）

      // 验证用户出现在列表中
      await expect(async () => {
        const exists = await userManagementPage.userExists(username);
        expect(exists).toBe(true);
      }).toPass({ timeout: TIMEOUTS.DIALOG });

      // 验证用户类型徽章显示为企业用户
      const userRow = userManagementPage.getUserByUsername(username);
      const userTypeBadge = userRow.getByTestId('user-type-badge');
      await expect(userTypeBadge).toContainText('企业用户');

      // 清理测试数据（用户）
      const deleteResult = await userManagementPage.deleteUser(username);
      expect(deleteResult).toBe(true);

      // 验证用户已被删除
      const existsAfterDelete = await userManagementPage.userExists(username);
      expect(existsAfterDelete).toBe(false);
    });

    test('创建后企业用户应该出现在列表中', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `employer_list_${timestamp}`;

      // 创建企业用户
      await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: '列表测试用户',
        userType: UserType.EMPLOYER,
      }, testCompanyName);

      // 验证用户出现在列表中
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(true);

      // 清理
      await userManagementPage.deleteUser(username);
    });
  });

  test.describe('完整表单字段测试', () => {
    test('应该成功创建完整信息企业用户', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `employer_full_${timestamp}`;

      // 创建企业用户（填写所有字段）
      const result = await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: '完整信息用户',
        email: `full_${timestamp}@example.com`,
        phone: '13800138000',
        name: '张三',
        userType: UserType.EMPLOYER,
        // companyId 由 Page Object 通过公司名称自动处理，无需指定
      }, testCompanyName);

      // 验证 API 响应成功
      const createResponse = result.responses?.find(r => r.url.includes('/api/v1/users'));
      expect(createResponse?.ok).toBe(true);

      // 验证用户出现在列表中
      await expect(async () => {
        const exists = await userManagementPage.userExists(username);
        expect(exists).toBe(true);
      }).toPass({ timeout: TIMEOUTS.DIALOG });

      // 清理
      await userManagementPage.deleteUser(username);
    });

    test('应该保存所有填写的字段数据', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `employer_fields_${timestamp}`;

      // 创建企业用户（填写所有字段）
      const result = await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: `字段测试_${timestamp}`,
        email: `fields_${timestamp}@test.com`,
        phone: '13900139000',
        name: '李四',
        userType: UserType.EMPLOYER,
        // companyId 由 Page Object 通过公司名称自动处理，无需指定
      }, testCompanyName);

      // 验证创建成功（优先检查 API 响应）
      const createResponse = result.responses?.find(r => r.url.includes('/api/v1/users'));
      expect(createResponse?.ok).toBe(true);

      // 验证创建成功提示（可选，Toast 检测可能不稳定）
      if (result.hasSuccess && result.successMessage) {
        expect(result.successMessage).toContain('成功');
      }

      // 验证用户出现在列表中
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(true);

      // 清理
      await userManagementPage.deleteUser(username);
    });
  });

  test.describe('公司关联验证测试', () => {
    // TODO: 后端当前未强制要求企业用户必须关联公司
    // 当前行为：后端允许创建没有 companyId 的 EMPLOYER 用户
    // 期望行为：后端应返回 400 错误，要求企业用户必须关联公司
    test.skip('企业用户必须关联公司 [后端验证未实现]', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `employer_no_company_${timestamp}`;

      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 填写用户名和密码
      await userManagementPage.usernameInput.fill(username);
      await userManagementPage.passwordInput.fill('password123');

      // 选择用户类型为企业用户（但不选择公司）
      await userManagementPage.page.waitForSelector('[data-testid="用户类型-trigger"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
      await userManagementPage.userTypeSelector.click();
      await userManagementPage.page.waitForSelector('[role="option"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
      await userManagementPage.page.getByRole('option', { name: '企业用户' }).click();

      // 尝试提交表单
      const submitResult = await userManagementPage.submitForm();

      // 验证 API 响应包含错误（后端验证）
      const createResponse = submitResult.responses?.find(r => r.url.includes('/api/v1/users'));
      // 后端应该返回 400 错误或 Toast 错误消息
      expect(createResponse?.ok || submitResult.hasError).toBe(false);

      // 验证用户没有被创建（列表中不存在）
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(false);
    });

    test.skip('不选择公司时应该显示错误提示 [后端验证未实现]', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `employer_error_${timestamp}`;

      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 填写必填字段
      await userManagementPage.usernameInput.fill(username);
      await userManagementPage.passwordInput.fill('password123');
      await userManagementPage.nicknameInput.fill('错误测试用户');

      // 选择用户类型为企业用户（但不选择公司）
      await userManagementPage.page.waitForSelector('[data-testid="用户类型-trigger"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
      await userManagementPage.userTypeSelector.click();
      await userManagementPage.page.waitForSelector('[role="option"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
      await userManagementPage.page.getByRole('option', { name: '企业用户' }).click();

      // 尝试提交表单
      const submitResult = await userManagementPage.submitForm();

      // 验证后端返回错误（公司必填验证）
      const createResponse = submitResult.responses?.find(r => r.url.includes('/api/v1/users'));
      expect(createResponse?.ok || submitResult.hasError).toBe(false);

      // 验证用户没有被创建
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(false);
    });
  });

  test.describe('表单验证测试', () => {
    test('用户名为空时应显示验证错误', async ({ userManagementPage }) => {
      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 不填写用户名，直接填写密码
      await userManagementPage.passwordInput.fill('password123');

      // 尝试提交表单
      await userManagementPage.submitForm();

      // 验证对话框仍然打开（表单验证阻止了提交）
      const dialog = userManagementPage.page.locator('[role="dialog"]');
      await expect(dialog).toBeVisible();

      // 关闭对话框
      await userManagementPage.cancelDialog();
    });

    test('密码为空时应显示验证错误', async ({ userManagementPage }) => {
      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 填写用户名，但不填写密码
      const timestamp = Date.now();
      await userManagementPage.usernameInput.fill(`user_no_pwd_${timestamp}`);

      // 尝试提交表单
      await userManagementPage.submitForm();

      // 验证对话框仍然打开（表单验证阻止了提交）
      const dialog = userManagementPage.page.locator('[role="dialog"]');
      await expect(dialog).toBeVisible();

      // 关闭对话框
      await userManagementPage.cancelDialog();
    });

    // 注意：昵称是可选字段（没有红色星号），所以表单会允许不填昵称提交
    // 此测试已移除，因为它测试的是不存在的验证

    test('邮箱格式不正确时应显示验证错误', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `user_bad_email_${timestamp}`;

      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 先填写无效格式的邮箱（在填写其他可选字段之前）
      await userManagementPage.usernameInput.fill(username);
      await userManagementPage.passwordInput.fill('password123');
      await userManagementPage.emailInput.fill('invalid-email-format');
      // 不填写昵称等其他字段，只测试邮箱格式验证

      // 尝试提交表单
      await userManagementPage.submitForm();

      // 验证对话框仍然打开（表单验证阻止了提交）
      const dialog = userManagementPage.page.locator('[role="dialog"]');
      await expect(dialog).toBeVisible();

      // 关闭对话框
      await userManagementPage.cancelDialog();
    });
  });

  test.describe('数据唯一性测试', () => {
    test('不同测试应该使用不同的用户名', async ({ userManagementPage }) => {
      // 生成两个不同的用户名
      const timestamp = Date.now();
      const username1 = `unique_employer_A_${timestamp}`;
      const username2 = `unique_employer_B_${timestamp}`;

      // 创建第一个企业用户
      await userManagementPage.createUser({
        username: username1,
        password: 'password123',
        nickname: '唯一性测试A',
        userType: UserType.EMPLOYER,
      }, testCompanyName);

      expect(await userManagementPage.userExists(username1)).toBe(true);

      // 创建第二个企业用户
      await userManagementPage.createUser({
        username: username2,
        password: 'password123',
        nickname: '唯一性测试B',
        userType: UserType.EMPLOYER,
      }, testCompanyName);

      expect(await userManagementPage.userExists(username2)).toBe(true);

      // 清理两个用户
      await userManagementPage.deleteUser(username1);
      await userManagementPage.deleteUser(username2);

      // 验证清理成功
      expect(await userManagementPage.userExists(username1)).toBe(false);
      expect(await userManagementPage.userExists(username2)).toBe(false);
    });

    test('使用时间戳确保用户名唯一', async ({ userManagementPage }) => {
      // 使用时间戳生成唯一用户名
      const timestamp = Date.now();
      const username = `timestamp_user_${timestamp}`;

      // 创建企业用户
      await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: '时间戳测试用户',
        userType: UserType.EMPLOYER,
      }, testCompanyName);

      // 验证用户创建成功
      expect(await userManagementPage.userExists(username)).toBe(true);

      // 清理
      await userManagementPage.deleteUser(username);
    });
  });

  test.describe('测试后清理验证', () => {
    test('应该能成功删除测试创建的企业用户', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `cleanup_employer_${timestamp}`;

      // 创建企业用户
      const result = await userManagementPage.createUser({
        username,
        password: 'password123',
        nickname: '清理测试用户',
        email: `cleanup_${timestamp}@test.com`,
        phone: '13800003333',
        userType: UserType.EMPLOYER,
      }, testCompanyName);

      // 验证用户存在
      const createResponse = result.responses?.find(r => r.url.includes('/api/v1/users'));
      expect(createResponse?.ok).toBe(true);
      expect(await userManagementPage.userExists(username)).toBe(true);

      // 删除用户
      const deleteResult = await userManagementPage.deleteUser(username);
      expect(deleteResult).toBe(true);

      // 验证用户已被删除
      await expect(async () => {
        const exists = await userManagementPage.userExists(username);
        expect(exists).toBe(false);
      }).toPass({ timeout: TIMEOUTS.DIALOG });
    });
  });

  test.describe('对话框元素验证', () => {
    test('应该显示创建用户对话框的所有字段', async ({ userManagementPage }) => {
      // 打开创建对话框
      await userManagementPage.openCreateDialog();

      // 验证对话框存在
      const dialog = userManagementPage.page.locator('[role="dialog"]');
      await expect(dialog).toBeVisible();

      // 验证用户类型选择器存在
      await expect(userManagementPage.userTypeSelector).toBeVisible();

      // 验证必填字段输入框存在
      await expect(userManagementPage.usernameInput).toBeVisible();
      await expect(userManagementPage.passwordInput).toBeVisible();
      await expect(userManagementPage.nicknameInput).toBeVisible();

      // 验证可选字段输入框存在
      await expect(userManagementPage.emailInput).toBeVisible();
      await expect(userManagementPage.phoneInput).toBeVisible();
      await expect(userManagementPage.nameInput).toBeVisible();

      // 企业选择器是条件渲染的，只有选择了 EMPLOYER 类型才会显示
      // 先选择企业用户类型
      await userManagementPage.userTypeSelector.click();
      await userManagementPage.page.waitForSelector('[role="option"]', { state: 'visible', timeout: TIMEOUTS.DIALOG });
      await userManagementPage.page.getByRole('option', { name: '企业用户' }).click();

      // 现在验证企业选择器存在
      await expect(userManagementPage.companySelector).toBeVisible();

      // 验证按钮存在
      await expect(userManagementPage.createSubmitButton).toBeVisible();
      await expect(userManagementPage.cancelButton).toBeVisible();

      // 关闭对话框
      await userManagementPage.cancelDialog();
    });
  });

  test.describe('取消和关闭操作测试', () => {
    test('应该能取消创建企业用户操作', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `cancel_employer_${timestamp}`;

      // 打开创建对话框并填写表单
      await userManagementPage.openCreateDialog();
      await userManagementPage.usernameInput.fill(username);
      await userManagementPage.passwordInput.fill('password123');

      // 点击取消按钮
      await userManagementPage.cancelDialog();

      // 验证对话框关闭
      const dialog = userManagementPage.page.locator('[role="dialog"]');
      await expect(dialog).not.toBeVisible();

      // 验证用户没有被创建
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(false);
    });

    test('应该能通过关闭对话框取消创建', async ({ userManagementPage }) => {
      const timestamp = Date.now();
      const username = `close_employer_${timestamp}`;

      // 打开创建对话框并填写表单
      await userManagementPage.openCreateDialog();
      await userManagementPage.usernameInput.fill(username);
      await userManagementPage.passwordInput.fill('password123');

      // 按 ESC 键关闭对话框
      await userManagementPage.page.keyboard.press('Escape');

      // 等待对话框关闭
      await userManagementPage.waitForDialogClosed();

      // 验证用户没有被创建
      const exists = await userManagementPage.userExists(username);
      expect(exists).toBe(false);
    });
  });
});
