import path from "node:path"
import { test as base, type Locator, type Page } from "@playwright/test"

import {
	createProjectViaApi,
	deleteProjectViaApi,
	loginAsAdmin,
} from "#tests/e2e/support/auth-api"

export const MOCK_SEGMENTS = [
	{ start_ms: 5000, end_ms: 8000 },
	{ start_ms: 15000, end_ms: 19000 },
	{ start_ms: 32000, end_ms: 35000 },
	{ start_ms: 45000, end_ms: 50000 },
]
export const MOCK_DURATION_MS = 60000
export const MOCK_TOTAL_REMOVED_MS = MOCK_SEGMENTS.reduce(
	(sum, s) => sum + (s.end_ms - s.start_ms),
	0,
)

interface FragmentsPage {
	page: Page
	projectId: string
	fragmentsStep: Locator
	jobId: string
}

export const test = base.extend<{ fragmentsPage: FragmentsPage }>({
	fragmentsPage: async ({ page }, use) => {
		const tokens = await loginAsAdmin()

		await page.context().addCookies([
			{
				name: "access_token",
				value: tokens.accessToken,
				domain: "localhost",
				path: "/",
			},
			{
				name: "refresh_token",
				value: tokens.refreshToken,
				domain: "localhost",
				path: "/",
			},
		])

		const suffix = Date.now().toString(36)
		const projectId = await createProjectViaApi(
			tokens.accessToken,
			`fragments-test-${suffix}`,
		)

		// Navigate to project wizard
		await page.goto(`/projects/${projectId}`)
		await page.locator("[data-testid='ProjectWizard']").waitFor()

		// Upload test video file
		const testVideoPath = path.resolve(
			__dirname,
			"../assets/test-video.mp4",
		)
		const fileInput = page
			.locator("[data-testid='UploadStep']")
			.locator("input[type='file']")
		await fileInput.setInputFiles(testVideoPath)

		// Wait for wizard to advance to Verify step
		await page
			.locator("[data-testid='VerifyStep']")
			.waitFor({ timeout: 30_000 })

		// Wait for file processing to complete
		await page
			.locator("[data-testid='VerifyStep']")
			.getByText("Готово к обработке")
			.waitFor({ timeout: 10_000 })

		// Advance to Silence Settings step
		await page
			.getByRole("button", { name: "Далее: Настройки тишины" })
			.click()

		const silenceStep = page.locator("[data-testid='SilenceSettingsStep']")
		await silenceStep.waitFor({ timeout: 10_000 })

		// Intercept task status polling — initially return RUNNING
		let taskStatusResponse = {
			status: "RUNNING",
			progress_pct: 0,
			output_data: null as Record<string, unknown> | null,
		}

		await page.route("**/api/tasks/status/**", async (route) => {
			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify(taskStatusResponse),
			})
		})

		// Capture job_id from the silence-detect submission
		let capturedJobId = ""
		page.on("response", async (res) => {
			if (
				res.url().includes("/api/tasks/silence-detect/") &&
				res.request().method() === "POST" &&
				res.status() === 200
			) {
				try {
					const body = await res.json()
					if (body?.job_id) capturedJobId = body.job_id
				} catch {
					// ignore
				}
			}
		})

		// Click "Далее" to submit silence detection
		await silenceStep.getByRole("button", { name: "Далее" }).click()

		// Wait for ProcessingStep to appear
		await page
			.locator("[data-testid='ProcessingStep']")
			.waitFor({ timeout: 10_000 })

		// Now switch the task status to DONE with mock data to trigger auto-advance
		taskStatusResponse = {
			status: "DONE",
			progress_pct: 100,
			output_data: {
				silent_segments: MOCK_SEGMENTS,
				duration_ms: MOCK_DURATION_MS,
			},
		}

		// Wait for auto-advance to FragmentsStep (polls every 2s)
		const fragmentsStep = page.locator("[data-testid='FragmentsStep']")
		await fragmentsStep.waitFor({ timeout: 15_000 })

		const fragmentsPage: FragmentsPage = {
			page,
			projectId,
			fragmentsStep,
			jobId: capturedJobId,
		}

		await use(fragmentsPage)

		// Cleanup: delete project
		try {
			await deleteProjectViaApi(tokens.accessToken, projectId)
		} catch {
			// Best-effort cleanup
		}
	},
})

export { expect } from "@playwright/test"
