/**
 * Sprint UI-deep, пункт 9: Reports — Sales/Stock/Profit/ABC.
 * Открываем каждый, проверяем что страница рендерится, фильтры работают,
 * и кнопки экспорта CSV/XLSX вызывают скачивание реального файла.
 */
import { test, expect, request as apiRequest } from '@playwright/test'
import { apiSignup, attachSession, watchPage, expectNoErrors } from '../lib/ui.js'

const BASE = process.env.E2E_ADMIN_URL ?? 'https://test.admin.food-market.kz'

// Один общий signup для всех тестов в этом file'е — иначе rate-limit
// signup'a (6/min) бьёт по тестам.
let sharedSess: Awaited<ReturnType<typeof apiSignup>> | null = null
async function sharedSession() {
  if (!sharedSess) sharedSess = await apiSignup('rep-shared')
  return sharedSess
}

test.describe('UI-9 reports + downloads', () => {
  test.describe.configure({ mode: 'serial' })

  for (const { name, path, expectExport } of [
    { name: 'Sales', path: '/reports/sales', expectExport: true },
    { name: 'Stock', path: '/reports/stock', expectExport: true },
    { name: 'Profit', path: '/reports/profit', expectExport: true },
    { name: 'ABC', path: '/reports/abc', expectExport: false },
  ] as const) {
    test(`9.${name} страница рендерится без console-errors`, async ({ page }) => {
      const sess = await sharedSession()
      const errs = watchPage(page)
      await attachSession(page, sess, path)
      await page.waitForLoadState('networkidle')
      // Какой-то контент
      const bodyText = await page.locator('main').innerText()
      expect(bodyText.length).toBeGreaterThan(50)

      if (expectExport) {
        // Кнопки CSV / XLSX
        await expect(page.getByRole('button', { name: /csv/i }).first()).toBeVisible({ timeout: 5_000 })
        await expect(page.getByRole('button', { name: /xlsx/i }).first()).toBeVisible({ timeout: 5_000 })
      }

      expectNoErrors(errs, `${name} report`)
    })
  }

  test('9.Sales: CSV скачивается и не пустой', async ({ page }) => {
    test.setTimeout(60_000)
    const sess = await sharedSession()
    const errs = watchPage(page)
    // Засидим демо чтобы в отчёте было что показывать (идемпотентно)
    const ctx = await apiRequest.newContext({
      baseURL: BASE, ignoreHTTPSErrors: true,
      extraHTTPHeaders: { Authorization: `Bearer ${sess.accessToken}` },
    })
    await ctx.post('/api/admin/seed-demo', { data: {} })
    await ctx.dispose()

    await attachSession(page, sess, '/reports/sales')
    await page.waitForLoadState('networkidle')

    // Жмём CSV
    const downloadPromise = page.waitForEvent('download', { timeout: 15_000 })
    await page.getByRole('button', { name: /csv/i }).first().click()
    const dl = await downloadPromise
    const filename = dl.suggestedFilename()
    expect(filename).toMatch(/\.csv$/i)
    const stream = await dl.createReadStream()
    let bytes = 0
    if (stream) {
      await new Promise<void>((resolve) => {
        stream.on('data', (chunk: Buffer) => { bytes += chunk.length })
        stream.on('end', () => resolve())
      })
    }
    expect(bytes, 'CSV не должен быть пустым').toBeGreaterThan(20)

    expectNoErrors(errs, 'sales csv download')
  })

  test('9.Stock: XLSX endpoint возвращает корректный response', async ({ page }) => {
    test.setTimeout(60_000)
    const sess = await sharedSession()
    const errs = watchPage(page)

    await attachSession(page, sess, '/reports/stock')
    await page.waitForLoadState('networkidle')

    // Слушаем XLSX-response (не download — этот endpoint у нас идёт через
    // axios+blob, и Chromium не всегда триггерит download event).
    const respPromise = page.waitForResponse(
      (r) => r.url().includes('/api/reports/stock/export') && r.url().includes('format=xlsx'),
      { timeout: 20_000 },
    )
    await page.getByRole('button', { name: /xlsx/i }).first().click()
    const resp = await respPromise
    expect(resp.status()).toBeLessThan(400)
    const ct = resp.headers()['content-type'] ?? ''
    expect(ct, 'Stock XLSX должен иметь правильный MIME').toMatch(/spreadsheetml|excel|octet/i)
    const body = await resp.body()
    expect(body.length, 'XLSX не должен быть пустым').toBeGreaterThan(100)

    expectNoErrors(errs, 'stock xlsx download')
  })
})
