/**
 * Sprint UI-deep, пункт 2: дашборд + навигация.
 * Прокликиваем каждый sidebar-пункт под Owner-Admin'ом, проверяем что
 * страница рендерится без console-errors и без 5xx/4xx ответов.
 */
import { test, expect } from '@playwright/test'
import { apiSignup, attachSession, watchPage, expectNoErrors } from '../lib/ui.js'

const NAV_PATHS = [
  { path: '/', heading: /быстрый старт|онбординг|главная|начать/i },
  { path: '/dashboard', heading: /выручка|обзор|аналитика|главная/i },
  { path: '/catalog/products', heading: /товары/i },
  { path: '/catalog/product-groups', heading: /группы/i },
  { path: '/catalog/units', heading: /ед\.|единиц/i },
  { path: '/catalog/price-types', heading: /типы цен/i },
  { path: '/catalog/counterparties', heading: /контрагент/i },
  { path: '/inventory/stock', heading: /остатк/i },
  { path: '/inventory/movements', heading: /движени/i },
  { path: '/inventory/enters', heading: /оприходован/i },
  { path: '/inventory/losses', heading: /списан/i },
  { path: '/inventory/transfers', heading: /перемещен/i },
  { path: '/inventory/inventories', heading: /инвентар/i },
  { path: '/purchases/supplies', heading: /приёмк|приемк/i },
  { path: '/purchases/supplier-returns', heading: /возврат/i },
  { path: '/sales/retail', heading: /рознич|чек/i },
  { path: '/sales/demands', heading: /оптов|отгрузк/i },
  { path: '/reports/sales', heading: /продаж/i },
  { path: '/reports/stock', heading: /остатк/i },
  { path: '/reports/profit', heading: /прибыл/i },
  { path: '/reports/abc', heading: /abc|анализ/i },
  { path: '/audit-log', heading: /журнал/i },
  { path: '/settings/organization', heading: /настройк/i },
  { path: '/catalog/stores', heading: /склад/i },
  { path: '/catalog/retail-points', heading: /касс/i },
  { path: '/settings/employees', heading: /сотрудник/i },
  { path: '/settings/employee-roles', heading: /рол/i },
] as const

test.describe('UI-2 dashboard + navigation', () => {
  test.describe.configure({ mode: 'serial' })

  test('2.1 каждая страница sidebar открывается без console-errors / 5xx', async ({ page }) => {
    test.setTimeout(180_000) // 27 страниц по ~5с = 135с
    const sess = await apiSignup('nav')
    const errs = watchPage(page, {
      // Stock/Reports на свежей орге могут отдавать 404 на отчёт если нет данных,
      // но это API уровень и сейчас не должно быть. Если запись «404 /api/...»
      // появится — это баг и тест упадёт.
    })
    await attachSession(page, sess, '/dashboard')
    await expect(page).toHaveURL(/\/dashboard/, { timeout: 10_000 })

    for (const { path } of NAV_PATHS) {
      await page.goto(path, { waitUntil: 'domcontentloaded' })
      // ждём первого heading на странице — это значит React-роут отработал
      await page.waitForLoadState('networkidle', { timeout: 20_000 })
      // <body> непустой
      const bodyText = await page.locator('body').innerText()
      expect(bodyText.length, `body не пустой на ${path}`).toBeGreaterThan(100)
    }

    expectNoErrors(errs, 'sidebar walk')
  })

  test('2.2 sidebar содержит все ожидаемые пункты', async ({ page }) => {
    const sess = await apiSignup('nav2')
    const errs = watchPage(page)
    await attachSession(page, sess, '/dashboard')

    const expectedLabels = [
      'Главная', 'Аналитика', 'Товары', 'Группы', 'Ед. измерения', 'Типы цен',
      'Контрагенты', 'Остатки', 'Движения', 'Оприходования', 'Списания',
      'Перемещения', 'Инвентаризации', 'Приёмки', 'Возвраты поставщикам',
      'Розничные чеки', 'Оптовые отгрузки', 'Продажи', 'Прибыль', 'ABC-анализ',
      'Журнал изменений', 'Общие', 'Склады', 'Кассы', 'Сотрудники', 'Роли',
    ]
    for (const lbl of expectedLabels) {
      // в sidebar nav (aside)
      await expect(
        page.locator('aside').getByRole('link', { name: new RegExp(`^${lbl}$`) }).first(),
        `пункт «${lbl}»`,
      ).toBeVisible({ timeout: 5_000 })
    }
    expectNoErrors(errs, 'sidebar labels')
  })

  test('2.3 клик по пункту меняет URL и активный стейт', async ({ page }) => {
    const sess = await apiSignup('nav3')
    const errs = watchPage(page)
    await attachSession(page, sess, '/dashboard')

    // Клик на «Товары»
    await page.locator('aside').getByRole('link', { name: /^Товары$/ }).first().click()
    await page.waitForURL(/\/catalog\/products/, { timeout: 10_000 })

    // Активный (текущий) пункт в sidebar — NavLink из react-router-dom добавляет
    // active class. Проверим через aria-current="page".
    const active = page.locator('aside a[aria-current="page"]')
    await expect(active).toHaveText(/Товары/, { timeout: 5_000 })

    expectNoErrors(errs, 'nav click')
  })

  test('2.4 несуществующий tenant-роут → редирект на онбординг / 404 без белого экрана', async ({ page }) => {
    const sess = await apiSignup('nav4')
    const errs = watchPage(page, {
      // 404 ожидаем — это и есть проверка
      expected4xxContains: ['/api/'],
    })
    await attachSession(page, sess, '/garbage-path-' + Date.now())
    await page.waitForLoadState('networkidle', { timeout: 10_000 })
    // body не должен быть пустым
    const bodyText = await page.locator('body').innerText()
    expect(bodyText.length).toBeGreaterThan(100)
    // sidebar всё ещё виден (приложение не упало)
    await expect(page.locator('aside').first()).toBeVisible()
  })
})
