import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

import { _electron as electron, expect, test } from '@playwright/test'

const here = dirname(fileURLToPath(import.meta.url))
const MAIN = join(here, '..', 'out', 'main', 'index.js')

// Opt-in only (GITEA_LIVE=1). Launches WITHOUT COMMITEA_E2E so the main process
// reconciles the real repo via .env.local, and asserts real data renders.
test.describe('live backlog', () => {
  test('The pot + Focus render real gitea data', async () => {
    test.skip(!process.env.GITEA_LIVE, 'GITEA_LIVE not set — opt-in live test')
    const app = await electron.launch({ args: [MAIN], env: { ...process.env } })
    const win = await app.firstWindow()
    await win.waitForLoadState('domcontentloaded')
    const rail = win.getByRole('navigation', { name: 'Primary' })

    // The pot — waiting here also lets the reconcile (issues + deps + timelines) complete
    await rail.getByRole('button', { name: 'The pot' }).click()
    await expect(win.getByText('Gitea read client behind an injected fetch')).toBeVisible({ timeout: 20000 })
    // Lifecycle inference (#5): columns come from the real event stream — merged
    // work lands in Done, so that column is non-empty (proves timelines drove it,
    // not the three-column fallback which would still show closed issues in Done).
    await expect(win.getByText('Done', { exact: true })).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-board.png'), fullPage: true, animations: 'disabled' })

    // Back to Focus — the deterministic scheduler's real Now/Next/Later. These
    // rationale phrases are emitted only by the scheduler, never by the demo fixture.
    await rail.getByRole('button', { name: 'Morning service' }).click()
    await expect(win.getByText(/on the critical path|unblocks #|waits on #|· ready/).first()).toBeVisible()
    // Real Monte Carlo cone — this headline is emitted only for real forecasts.
    await expect(win.getByText(/80% of the open backlog lands by/)).toBeVisible()
    await expect(win.getByText(/Cold-start priors/)).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-focus.png'), fullPage: true, animations: 'disabled' })

    // Runway → calibration surface, fitted from real closed-issue actuals (#1).
    // With <20 estimated closes the repo is honestly cold-start; the note proves
    // the fit ran on real data, not the fixture's "calibrated on 27".
    await rail.getByRole('button', { name: 'Runway' }).click()
    await expect(
      win.getByText(/cold-start priors · \d+\/20 closed issues estimated|calibrated on \d+ closed/),
    ).toBeVisible()
    // Real per-milestone forecasts — these milestone names come from gitea, not the
    // fixture (which lists Beta / Pilot-ready / v1.0).
    await expect(win.getByText(/P2 — Scheduler/)).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-runway.png'), fullPage: true, animations: 'disabled' })

    // Milestone drill-in — clicking a real milestone opens its real detail
    await win.getByText(/P2 — Scheduler/).click()
    await expect(win.getByRole('heading', { name: 'P2 — Scheduler + Monte Carlo' })).toBeVisible()
    await expect(win.getByText(/\d+ issues · est \d+d/)).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-milestone.png'), fullPage: true, animations: 'disabled' })
    await rail.getByRole('button', { name: 'Runway' }).click()

    await win.getByRole('button', { name: 'Full report' }).click()
    await expect(win.getByText(/cold-start · \d+\/20|curve active · n ≥ 20/)).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-calibration.png'), fullPage: true, animations: 'disabled' })

    // Write path (apply_changes): open the top scheduled issue, propose an
    // estimate change, and confirm the propose-approve diff renders — then CANCEL
    // so the live run never mutates the real repo (the PUT is unit-tested; a
    // one-off change→revert verified it against gitea manually).
    await rail.getByRole('button', { name: 'Morning service' }).click()
    await win.getByRole('main').getByRole('link').first().click()
    await expect(win.getByText(/· stephen\/commitea/)).toBeVisible()
    await win.getByRole('button', { name: 'Adjust' }).click()
    await expect(win.getByText('Adjust estimate & priority')).toBeVisible()
    await win.getByRole('combobox').first().selectOption('est/8d')
    await expect(win.getByText('Proposed label change')).toBeVisible()
    await expect(win.getByText(/est\/8d/).last()).toBeVisible()
    await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-apply-change.png'), fullPage: true, animations: 'disabled' })
    await win.getByRole('button', { name: 'Cancel' }).click() // no mutation

    await app.close()
  })
})
