import { expect, test } from './authenticated-test.js';

/**
 * 代码作用（白话）：拦截手机号资产列表请求，给弹窗测试准备不依赖后端的空列表。
 * 关联文件：PhoneAssetView.js、phone-api-client.js。
 * 关联逻辑（调用链/数据流）：页面打开 -> listPhoneAssets -> 浏览器路由拦截 -> 空列表 -> 新增弹窗。
 */
async function mockPhoneAssetList(page) {
  await page.route('**/api/phone-assets?**', async (route) => {
    await route.fulfill({
      contentType: 'application/json',
      body: JSON.stringify({
        code: 200,
        message: 'success',
        data: { records: [], total: 0, page: 1, size: 20 }
      })
    });
  });
}

/**
 * 代码作用（白话）：打开新增手机号资产弹窗，供多个验收场景复用。
 * 关联文件：PhoneAssetView.js、phone-asset.spec.js。
 * 关联逻辑（调用链/数据流）：测试页面 -> 新增按钮 -> openCreate -> dialogVisible -> 弹窗。
 */
async function openCreateDialog(page) {
  await mockPhoneAssetList(page);
  await page.goto('/#/phone-assets');
  await page.getByRole('button', { name: '新增手机号资产' }).click();
  return page.getByRole('dialog', { name: '新增手机号资产' });
}

/**
 * 代码作用（白话）：在浏览器中派发带剪贴板文字的真实粘贴事件。
 * 关联文件：PhoneAssetView.js、phone-asset.spec.js。
 * 关联逻辑（调用链/数据流）：测试数据 -> paste 事件 -> handlePhonePaste/handleIccidPaste -> 表单字段。
 */
async function pasteText(locator, value) {
  await locator.evaluate((input, pastedValue) => {
    const clipboardData = new DataTransfer();
    clipboardData.setData('text', pastedValue);
    input.dispatchEvent(new ClipboardEvent('paste', { bubbles: true, cancelable: true, clipboardData }));
  }, value);
}
/**
 * 代码作用（白话）：验证新增弹窗保留七个字段，并将两个字数计数器放在各自输入框内部。
 * 关联文件：PhoneAssetView.js、app.css。
 * 关联逻辑（调用链/数据流）：新增按钮 -> 弹窗渲染 -> 表单字段和 suffix 计数器。
 */
test('新增弹窗保留七个字段，并在输入框内显示初始计数器', async ({ page }) => {
  const dialog = await openCreateDialog(page);
  await expect(dialog.locator('.phone-asset-modal__form-row')).toHaveCount(7);
  await expect(dialog.locator('.phone-asset-modal__character-count')).toHaveText(['0/11', '0/20']);
  await expect(dialog.locator('.phone-asset-modal__character-count').first()).toBeVisible();
});

/**
 * 代码作用（白话）：验证手机号和 ICCID 的输入、粘贴、删除都会实时更新计数器且不会超过长度上限。
 * 关联文件：PhoneAssetView.js、app.css。
 * 关联逻辑（调用链/数据流）：输入事件 -> limitPhoneNumber/limitIccid -> form -> suffix 计数器。
 */
test('手机号和 ICCID 会过滤并截断超长输入，同时更新框内计数器', async ({ page }) => {
  const dialog = await openCreateDialog(page);
  const phoneInput = dialog.getByLabel('手机号');
  const iccidInput = dialog.getByLabel('ICCID');

  await pasteText(phoneInput, '138-1234567899');
  await expect(phoneInput).toHaveValue('13812345678');
  await expect(dialog.locator('.phone-asset-modal__character-count').first()).toHaveText('11/11');
  await phoneInput.press('Control+A');
  await phoneInput.press('Backspace');
  await expect(dialog.locator('.phone-asset-modal__character-count').first()).toHaveText('0/11');

  await pasteText(iccidInput, '8986032594020999545B-extra');
  await expect(iccidInput).toHaveValue('8986032594020999545B');
  await expect(dialog.locator('.phone-asset-modal__character-count').nth(1)).toHaveText('20/20');
});

/**
 * 代码作用（白话）：验证取消和右上角关闭按钮仍会关闭同一个业务弹窗。
 * 关联文件：PhoneAssetView.js。
 * 关联逻辑（调用链/数据流）：按钮点击 -> dialogVisible=false -> Element Plus 弹窗关闭。
 */
test('取消和右上角关闭按钮仍可关闭弹窗', async ({ page }) => {
  let dialog = await openCreateDialog(page);
  await dialog.getByRole('button', { name: '取消' }).click();
  await expect(dialog).toBeHidden();

  dialog = await openCreateDialog(page);
  await dialog.locator('.el-dialog__headerbtn').click();
  await expect(dialog).toBeHidden();
});
/**
 * 代码作用（白话）：验证确认保存仍将原有表单字段通过新增接口提交。
 * 关联文件：PhoneAssetView.js、phone-api-client.js、PhoneAssetController.java。
 * 关联逻辑（调用链/数据流）：确认保存 -> createPhoneAsset -> POST /api/phone-assets -> 成功提示和关闭弹窗。
 */
test('确认保存仍调用原有新增接口并提交表单数据', async ({ page }) => {
  let submittedPayload;
  await page.route('**/api/phone-assets', async (route) => {
    if (route.request().method() !== 'POST') return route.fallback();
    submittedPayload = route.request().postDataJSON();
    await route.fulfill({
      contentType: 'application/json',
      body: JSON.stringify({ code: 200, message: '新增成功', data: { id: 1 } })
    });
  });
  const dialog = await openCreateDialog(page);
  await dialog.getByLabel('手机号').fill('13812345678');
  await dialog.getByRole('button', { name: '确认保存' }).click();
  await expect.poll(() => submittedPayload?.phoneNumber).toBe('13812345678');
  await expect(dialog).toBeHidden();
});

/**
 * 代码作用（白话）：验证窄窗口里的弹窗保持在可视区域内，页面不出现横向滚动条。
 * 关联文件：PhoneAssetView.js、app.css。
 * 关联逻辑（调用链/数据流）：窄视口 -> 响应式 CSS -> 单列表单和受限弹窗宽度。
 */
test('窄窗口下弹窗不超出屏幕且页面没有横向滚动', async ({ page }) => {
  await page.setViewportSize({ width: 320, height: 640 });
  const dialog = await openCreateDialog(page);
  const bounds = await dialog.boundingBox();
  expect(bounds).not.toBeNull();
  expect(bounds.x).toBeGreaterThanOrEqual(0);
  expect(bounds.x + bounds.width).toBeLessThanOrEqual(320);
  await expect.poll(() => page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true);
});
