import { expect, test } from '@playwright/test'
import { startFixtureCollector, type FixtureCollector } from './fixture-collector'
import {
  CI_BUILD_INCIDENT_ITEMS,
  CI_BUILD_INCIDENT_PANELS,
  CI_BUILD_OFFLOAD_ADAPTER,
} from './fixtures/ci-build-fixtures'
import { ADAPTER_STATUSES, ALL_ITEMS, ALL_PANELS, CI_ONLY_PANELS, RUN_ID } from './fixtures/collector-fixtures'
import { FACTORY_ADW_ID, FACTORY_RUNNING_RUN } from './fixtures/factory-fixtures'

test.describe.configure({ mode: 'serial' })

let collector: FixtureCollector

const FULL_STATE = {
  panels: [...ALL_PANELS.filter((panel) => panel.id !== 'ci'), ...CI_BUILD_INCIDENT_PANELS],
  adapters: [...ADAPTER_STATUSES, CI_BUILD_OFFLOAD_ADAPTER],
  items: [...ALL_ITEMS, ...CI_BUILD_INCIDENT_ITEMS],
}

async function expandOverdeckProjectGroup(page: import('@playwright/test').Page) {
  const overdeckGroup = page.getByTestId('project-group-row').filter({ hasText: 'overdeck' })
  await overdeckGroup.getByRole('button', { name: 'Expand overdeck' }).click()
  await expect(page.getByRole('table', { name: 'Plans' }).locator('tbody tr').first()).toBeVisible()
}

test.beforeAll(async () => {
  collector = await startFixtureCollector(FULL_STATE)
})

test.afterAll(async () => {
  await collector.close()
})

const SIDEBAR_PAGES = [
  { path: '/plans', heading: 'Plan runs' },
  { path: '/factory', heading: 'Factory runs' },
  { path: '/agents', heading: 'Agent fleet', snippet: 'agents live' },
  { path: '/ci', heading: 'CI runners', snippet: 'alexcodeplace/multideal #4821' },
  { path: '/bots', heading: 'Bots (Botmaster)', snippet: 'dealbot' },
  { path: '/limits', heading: 'Limits & Spend', snippet: 'claude A' },
  { path: '/gates', heading: 'Gates', snippet: 'slopgate debt' },
  { path: '/projects', heading: 'multideal', snippet: '/34' },
  { path: '/settings', heading: 'Project colors', snippet: 'golive' },
] as const

for (const entry of SIDEBAR_PAGES) {
  test(`${entry.path} renders non-empty fixture content`, async ({ page }) => {
    const ciOnly = entry.path === '/ci'
    if (ciOnly) {
      collector.replaceState({
        panels: CI_ONLY_PANELS,
        adapters: ADAPTER_STATUSES.filter((adapter) => adapter.id === 'ghci'),
        items: [],
      })
    }
    try {
      await page.goto(entry.path)
      await expect(page.getByRole('heading', { level: 4, name: entry.heading })).toBeVisible()
      if (entry.path === '/plans') {
        const overdeckGroup = page.getByTestId('project-group-row').filter({ hasText: 'overdeck' })
        await expect(overdeckGroup.getByText('1 need you', { exact: true })).toBeVisible()
      } else if (entry.path === '/factory') {
        const card = page.getByTestId('factory-run-card')
        await expect(card.getByLabel(`Repository ${FACTORY_RUNNING_RUN.repo}`)).toBeVisible()
        const phaseTable = card.getByTestId('factory-phase-table')
        await expect(phaseTable.getByRole('cell', { name: 'implement', exact: true })).toBeVisible()
        await expect(phaseTable.getByRole('cell', { name: 'est. $0.1800', exact: true })).toBeVisible()
        await expect(card.getByText(`factory stop ${FACTORY_ADW_ID}`)).toBeVisible()
      } else {
        await expect(page.getByText(entry.snippet)).toBeVisible()
      }
    } finally {
      if (ciOnly) collector.replaceState(FULL_STATE)
    }
  })
}

test('plan rows link to the componentized run detail page', async ({ page }) => {
  await page.goto('/plans')
  await expandOverdeckProjectGroup(page)
  const link = page.locator(`[data-plan-run-link="${RUN_ID}"]`)
  await expect(link).toHaveAttribute('href', `/plans/${RUN_ID}`)
  await link.click()
  await expect(page.getByRole('heading', { name: 'tasks truly landed' })).toBeVisible()
  await expect(page.getByText('config surface needs B5')).toBeVisible()
})

test('clicking a plan row opens the run detail page', async ({ page }) => {
  await page.goto('/plans')
  await expandOverdeckProjectGroup(page)
  await expect(page.getByRole('button', { name: 'Open run' })).toHaveCount(0)
  const row = page.getByRole('table', { name: 'Plans' }).locator('tbody tr').first()
  await row.click()
  await expect(page).toHaveURL(`/plans/${RUN_ID}`)
  await expect(page.getByRole('heading', { name: 'tasks truly landed' })).toBeVisible()
})

test('settings color override round-trips through POST /config/projects', async ({ page }) => {
  await page.goto('/settings')
  await expect(page.getByRole('heading', { level: 4, name: 'Project colors' })).toBeVisible()

  const input = page.locator('[data-project-color-input="multideal"]')
  await input.fill('#ff00aa')
  await page.locator('[data-save-project-colors]').click()
  await expect(page.locator('[data-save-message]')).toContainText('Saved')

  const response = await page.request.get('/api/collector/config/projects')
  expect(response.ok()).toBeTruthy()
  const body = (await response.json()) as { projects: Record<string, string> }
  expect(body.projects.multideal).toBe('#ff00aa')

  await page.reload()
  await expect(input).toHaveValue('#ff00aa')
})
