import { test, expect } from '@playwright/test'

// AZ-461 — e2e companion for sync image detect.
//
// AC-1 (FT-P-11): clicking the Detect button on an image issues exactly one
//                 POST whose URL matches `^/api/detect/[0-9]+$`.
// AC-2 (FT-P-12) — async video detect — is QUARANTINEd in CI (fast-profile
//                  it.fails() handles the assertion shape; the e2e companion
//                  intentionally omits it until AC-25 lands so the suite-e2e
//                  lane stays green).
// AC-3 (FT-P-13): drift today — `test.fail()` until production adds the
//                 `X-Refresh-Token` header for long-video detect.
//
// Requires the suite docker-compose stack and a media fixture exposing at
// least one image item that the Detect button can target. Skips with a clear
// reason when the seed is absent.

test.describe('AZ-461 — detection endpoints (e2e companion)', () => {
  test('AC-1 (FT-P-11) — sync image detect URL canary', async ({ page }) => {
    const detectRequests: { url: string; method: string }[] = []
    await page.route('**/api/detect/**', async (route) => {
      const req = route.request()
      detectRequests.push({ url: req.url(), method: req.method() })
      await route.continue()
    })

    await page.goto('/annotations')
    const detectBtn = page.getByRole('button', { name: /AI Detect/i }).first()
    if (!(await detectBtn.isVisible({ timeout: 5000 }).catch(() => false))) {
      test.skip(true, 'Suite seed has no media for detect')
    }
    if (await detectBtn.isDisabled().catch(() => true)) {
      // Need a media selected first. Click the first media-list row.
      const firstMedia = page.locator('div.cursor-pointer').first()
      if (!(await firstMedia.isVisible({ timeout: 5000 }).catch(() => false))) {
        test.skip(true, 'No media row visible for detect target')
      }
      await firstMedia.click()
    }

    await detectBtn.click({ timeout: 5000 }).catch(() => {})

    await page.waitForFunction(
      () => true,
      undefined,
      { timeout: 3000 },
    ).catch(() => null)

    expect(detectRequests.length).toBeGreaterThan(0)
    for (const r of detectRequests) {
      const path = new URL(r.url).pathname
      expect(path).toMatch(/^\/api\/detect\/[0-9a-zA-Z-]+$/)
      expect(r.method).toBe('POST')
    }
  })

  test.fail('AC-3 (FT-P-13) — long-video detect carries `X-Refresh-Token` header (drift)', async ({ page }) => {
    const headersByUrl: Record<string, Record<string, string>> = {}
    await page.route('**/api/detect/**', async (route) => {
      const req = route.request()
      headersByUrl[req.url()] = req.headers()
      await route.continue()
    })

    await page.goto('/annotations')
    const detectBtn = page.getByRole('button', { name: /AI Detect/i }).first()
    if (!(await detectBtn.isVisible({ timeout: 5000 }).catch(() => false))) {
      test.skip(true, 'Suite seed has no media for detect')
    }
    if (await detectBtn.isDisabled().catch(() => true)) {
      const firstMedia = page.locator('div.cursor-pointer').first()
      await firstMedia.click({ timeout: 5000 }).catch(() => {})
    }
    await detectBtn.click({ timeout: 5000 }).catch(() => {})

    await page.waitForTimeout(1000)
    const urls = Object.keys(headersByUrl)
    expect(urls.length).toBeGreaterThan(0)
    for (const u of urls) {
      const h = headersByUrl[u]
      expect(h).toHaveProperty('x-refresh-token')
      expect(h['x-refresh-token']).not.toBe('')
    }
  })
})
