import { test, expect, Page } from '@playwright/test';
import { setupApiMonitor, ApiError } from './helpers';

// echo 账号有员工身份，可以开班和收银
const EMAIL = 'echo@shboka.com';
const PASSWORD = '123456';
const STORE = 'boka-nail';

async function loginAndEnterStore(page: Page) {
  await page.goto('/login');
  await page.getByLabel('邮箱').fill(EMAIL);
  await page.getByLabel('密码').fill(PASSWORD);
  await page.getByRole('button', { name: '登录' }).click();
  await expect(page.getByText('选择门店')).toBeVisible({ timeout: 10000 });
  await page.getByRole('button', { name: STORE }).click();
  await page.getByRole('button', { name: '进入门店' }).click();
  await expect(page.getByRole('heading', { name: '工作台' })).toBeVisible({ timeout: 10000 });
}

async function enterPOS(page: Page) {
  // 导航到收银页面
  await page.goto('/pos/orders');
  await expect(page.getByRole('heading', { name: '收银' })).toBeVisible({ timeout: 10000 });

  // 点击收银台按钮
  await page.getByRole('button', { name: '收银台' }).click();
  await page.waitForTimeout(1000);

  // 如果未开班，先开班
  const openShiftBtn = page.getByRole('button', { name: '开班' });
  if (await openShiftBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
    await openShiftBtn.click();
    await page.waitForTimeout(500);
    // 输入备用金
    const amountInput = page.getByRole('spinbutton');
    if (await amountInput.isVisible({ timeout: 2000 }).catch(() => false)) {
      await amountInput.fill('500');
    }
    await page.getByRole('button', { name: '确认' }).click();
    await page.waitForTimeout(2000);
  }
}

async function addServiceToCart(page: Page, serviceName: string) {
  // 切换到服务分类
  await page.getByRole('button', { name: '服务' }).click();
  await page.waitForTimeout(500);
  // 点击服务
  await page.getByRole('button', { name: new RegExp(serviceName) }).click();
  await page.waitForTimeout(500);
}

async function goToPayment(page: Page) {
  // 购物车 → 小费
  await page.getByRole('button', { name: '继续付款 ›' }).click();
  await expect(page.getByRole('heading', { name: '小费' })).toBeVisible({ timeout: 5000 });
  // 无小费
  await page.getByRole('button', { name: '无小费' }).click();
  await page.waitForTimeout(300);
  // 小费 → 付款
  await page.getByRole('button', { name: '继续付款 ›' }).click();
  await expect(page.getByText('支付方式')).toBeVisible({ timeout: 5000 });
}

async function confirmPayment(page: Page) {
  await page.getByRole('button', { name: /确认收款/ }).click();
  await page.waitForTimeout(3000);
}

// ═══════════════════════════════════════════
// 散客做单子
// ═══════════════════════════════════════════
test.describe('散客做单流程', () => {

  test('散客 - 单服务现金结账', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 不选客户 = 散客
    await addServiceToCart(page, '纯色美甲');

    // 验证购物车
    const cart = page.getByRole('complementary');
    await expect(cart.getByText('¥88.00').first()).toBeVisible();

    // 走到付款
    await goToPayment(page);

    // 验证客户来源是散客
    await expect(page.getByText('散客')).toBeVisible();

    // 验证应收金额
    await expect(page.getByText('¥88.00').first()).toBeVisible();

    // 确认收款
    await confirmPayment(page);

    // 验证 API 无错误
    await monitor.expectNoApiErrors();
  });

  test('散客 - 多服务结账', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 加两个服务
    await addServiceToCart(page, '纯色美甲');
    await addServiceToCart(page, '渐变美甲');

    // 验证合计 88 + 138 = 226
    const cart = page.getByRole('complementary');
    await expect(cart.getByText('¥226.00').first()).toBeVisible();

    // 走到付款
    await goToPayment(page);

    // 确认收款
    await confirmPayment(page);
    await monitor.expectNoApiErrors();
  });

  test('散客 - 带小费结账', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    await addServiceToCart(page, '纯色美甲');

    // 购物车 → 小费
    await page.getByRole('button', { name: '继续付款 ›' }).click();
    await expect(page.getByRole('heading', { name: '小费' })).toBeVisible({ timeout: 5000 });

    // 选 10% 小费
    await page.getByRole('button', { name: '10%' }).click();
    await page.waitForTimeout(300);

    // 小费 → 付款
    await page.getByRole('button', { name: '继续付款 ›' }).click();
    await expect(page.getByText('支付方式')).toBeVisible({ timeout: 5000 });

    // 确认收款
    await confirmPayment(page);
    await monitor.expectNoApiErrors();
  });

  test('散客 - 购物车删除项目', async ({ page }) => {
    await loginAndEnterStore(page);
    await enterPOS(page);

    await addServiceToCart(page, '纯色美甲');
    await addServiceToCart(page, '渐变美甲');

    // 删除第一个
    const cart = page.getByRole('complementary');
    await cart.getByRole('button', { name: '删除' }).first().click();
    await page.waitForTimeout(500);

    // 合计应该只剩 138
    await expect(cart.getByText('¥138.00').first()).toBeVisible();
  });

  test('散客 - 返回不产生错误', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    await addServiceToCart(page, '纯色美甲');

    // 返回
    await page.getByRole('button', { name: '返回' }).click();
    await expect(page.getByRole('heading', { name: '收银' })).toBeVisible({ timeout: 5000 });

    await monitor.expectNoApiErrors();
  });
});

// ═══════════════════════════════════════════
// 会员做单子
// ═══════════════════════════════════════════
test.describe('会员做单流程', () => {

  test('会员 - 搜索并关联会员后结账', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 搜索会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);

    // 选择会员 Ada
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 验证会员已关联
    await expect(page.getByText('Ada')).toBeVisible();
    await expect(page.getByText('876542211111')).toBeVisible();

    // 加服务
    await addServiceToCart(page, '纯色美甲');

    // 走到付款
    await goToPayment(page);

    // 验证会员权益显示
    await expect(page.getByText('会员权益')).toBeVisible();

    // 确认收款
    await confirmPayment(page);
    await monitor.expectNoApiErrors();
  });

  test('会员 - 切换会员', async ({ page }) => {
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 搜索并选择 Ada
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 验证 Ada 已选中
    await expect(page.getByText('Ada')).toBeVisible();

    // 点切换会员
    const switchBtn = page.getByRole('button', { name: '切换会员' });
    if (await switchBtn.isVisible({ timeout: 2000 }).catch(() => false)) {
      await switchBtn.click();
      await page.waitForTimeout(500);
      // 应该回到搜索状态
      await expect(page.getByPlaceholder('搜索客户（名字/手机号）...')).toBeVisible();
    }
  });

  test('会员 - 新建会员', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 搜索一个不存在的名字
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('E2E新会员测试');
    await page.waitForTimeout(1000);

    // 应该出现"新建会员"选项
    const createBtn = page.getByRole('button', { name: /新建会员/ });
    if (await createBtn.isVisible({ timeout: 3000 }).catch(() => false)) {
      await createBtn.click();
      await page.waitForTimeout(1000);
      // 验证没有 API 错误
      await monitor.expectNoApiErrors();
    }
  });

  test('会员 - 多服务结账', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 加两个服务
    await addServiceToCart(page, '纯色美甲');
    await addServiceToCart(page, '渐变美甲');

    // 走到付款
    await goToPayment(page);

    // 确认收款
    await confirmPayment(page);
    await monitor.expectNoApiErrors();
  });
});

// ═══════════════════════════════════════════
// 会员核销（权益抵扣）
// ═══════════════════════════════════════════
test.describe('会员核销流程', () => {

  test('核销 - 付款页面显示会员权益信息', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员 Ada
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 加服务
    await addServiceToCart(page, '纯色美甲');

    // 走到付款
    await goToPayment(page);

    // 验证会员权益区域
    await expect(page.getByText('会员权益')).toBeVisible();
    await expect(page.getByText('Silver')).toBeVisible();

    // 验证储值卡选项存在
    await expect(page.getByText('储值卡')).toBeVisible();

    // 验证代金券区域存在
    await expect(page.getByText('代金券', { exact: true })).toBeVisible();

    // 验证 member_card 支付方式存在（可能是中文或英文显示）
    await expect(page.getByText(/member_card|会员卡/).first()).toBeVisible();

    await monitor.expectNoApiErrors();
  });

  test('核销 - 储值卡抵扣（余额为0时不可用）', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员 Ada（储值卡余额 ¥0.00）
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    await addServiceToCart(page, '纯色美甲');
    await goToPayment(page);

    // 储值卡余额为 0，显示 ¥0.00
    await expect(page.getByText('储值卡')).toBeVisible();

    // 验证应收仍然是 88（没有抵扣）
    await expect(page.getByText('应收')).toBeVisible();

    await monitor.expectNoApiErrors();
  });

  test('核销 - 促销码输入', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    await addServiceToCart(page, '纯色美甲');
    await goToPayment(page);

    // 输入促销码
    const promoInput = page.getByPlaceholder('输入促销码');
    await expect(promoInput).toBeVisible();
    await promoInput.fill('TEST100');
    await page.waitForTimeout(300);

    // 应用按钮应该激活
    const applyBtn = page.getByRole('button', { name: '应用' }).first();
    await expect(applyBtn).toBeEnabled();

    // 点应用（可能报错，但不应该 500）
    await applyBtn.click();
    await page.waitForTimeout(2000);

    // 不应该有 500 错误（400 是可以的，比如促销码无效）
    const serverErrors = monitor.errors.filter(e => e.status >= 500);
    expect(serverErrors).toHaveLength(0);
  });

  test('核销 - 礼品卡码输入', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    await addServiceToCart(page, '纯色美甲');
    await goToPayment(page);

    // 输入礼品卡码
    const giftInput = page.getByPlaceholder('输入礼品卡码');
    await expect(giftInput).toBeVisible();
    await giftInput.fill('GIFT-TEST-001');
    await page.waitForTimeout(300);

    // 应用按钮应该激活
    const applyBtns = page.getByRole('button', { name: '应用' });
    const lastApply = applyBtns.last();
    await expect(lastApply).toBeEnabled();

    await lastApply.click();
    await page.waitForTimeout(2000);

    // 不应该有 500 错误
    const serverErrors = monitor.errors.filter(e => e.status >= 500);
    expect(serverErrors).toHaveLength(0);
  });

  test('核销 - 次卡分类浏览', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 切换到次卡分类
    await page.getByRole('button', { name: '次卡' }).click();
    await page.waitForTimeout(1000);

    // 不应该有 API 错误
    await monitor.expectNoApiErrors();
  });

  test('核销 - 套餐分类浏览', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 关联会员
    const customerSearch = page.getByPlaceholder('搜索客户（名字/手机号）...');
    await customerSearch.fill('Ada');
    await page.waitForTimeout(1000);
    await page.getByRole('button', { name: /Ada/ }).first().click();
    await page.waitForTimeout(500);

    // 切换到套餐分类
    await page.getByRole('button', { name: '套餐' }).click();
    await page.waitForTimeout(1000);

    await monitor.expectNoApiErrors();
  });

  test('核销 - 储值方案分类浏览', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await enterPOS(page);

    // 切换到储值方案
    await page.getByRole('button', { name: '储值方案' }).click();
    await page.waitForTimeout(1000);

    await monitor.expectNoApiErrors();
  });
});

// ═══════════════════════════════════════════
// 订单列表操作
// ═══════════════════════════════════════════
test.describe('订单列表操作', () => {

  test('订单标签切换', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await page.goto('/pos/orders');
    await expect(page.getByRole('heading', { name: '收银' })).toBeVisible({ timeout: 10000 });

    // 切换各标签
    for (const tab of ['未结账', '已完成', '已作废', '全部订单']) {
      await page.getByRole('button', { name: tab }).click();
      await page.waitForTimeout(1000);
    }

    await monitor.expectNoApiErrors();
  });

  test('员工筛选', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await page.goto('/pos/orders');
    await expect(page.getByRole('heading', { name: '收银' })).toBeVisible({ timeout: 10000 });

    const employeeFilter = page.locator('select').filter({ hasText: '全部员工' });
    await employeeFilter.selectOption({ label: 'echo' });
    await page.waitForTimeout(1500);
    await monitor.expectNoApiErrors();

    await employeeFilter.selectOption({ label: '全部员工' });
    await page.waitForTimeout(1000);
  });

  test('搜索订单', async ({ page }) => {
    const monitor = setupApiMonitor(page);
    await loginAndEnterStore(page);
    await page.goto('/pos/orders');
    await expect(page.getByRole('heading', { name: '收银' })).toBeVisible({ timeout: 10000 });

    await page.getByPlaceholder('客户名或交易号...').fill('Ada');
    await page.getByRole('button', { name: '搜索' }).click();
    await page.waitForTimeout(2000);

    await monitor.expectNoApiErrors();
  });
});
