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

const USER_ID = "00000000-0000-0000-0000-000000000001"
const PROJECT_ID = "75df675b-013b-4b1f-ab2d-075dadbcd0d9"
const APPLY_JOB_ID = "00000000-0000-0000-0000-000000000051"
const TRANSCRIPTION_JOB_ID = "00000000-0000-0000-0000-000000000052"
const ORIGINAL_FILE_ID = "00000000-0000-0000-0000-000000000060"
const CUT_FILE_ID = "00000000-0000-0000-0000-000000000061"
const ORIGINAL_FILE_KEY = "projects/test/original-video.mp4"
const ORIGINAL_FILE_URL = "http://localhost:4444/files/original-video.mp4"
const CUT_FILE_KEY = "projects/test/cut-video.mp4"
const CUT_FILE_URL = "http://localhost:4444/files/cut-video.mp4"

const DEFAULT_USER = {
	id: USER_ID,
	username: "testuser",
	email: "test@example.com",
	first_name: "Test",
	last_name: "User",
	phone_number: null,
	avatar: null,
	email_verified: true,
	phone_verified: false,
	is_active: true,
	is_staff: false,
	is_superuser: false,
	date_joined: "2025-01-01T00:00:00Z",
}

const MOCK_SEGMENTS = [
	{ start_ms: 5000, end_ms: 8000 },
	{ start_ms: 15000, end_ms: 19000 },
]

test.describe("Silence Apply Flow", () => {
	test("should persist cuts via workflow actions and continue to transcription on processed source file", async ({
		page,
	}) => {
		let applyStatus: "RUNNING" | "DONE" = "RUNNING"
		const workflowActions: Array<Record<string, unknown>> = []
		let workspace: Record<string, any> = {
			revision: 1,
			phase: "SILENCE",
			current_screen: "fragments",
			active_job: null,
			source_file_id: ORIGINAL_FILE_ID,
			workspace_view: {
				used_file_ids: [],
				selected_file_id: null,
			},
			silence: {
				status: "REVIEW_READY",
				settings: {
					min_silence_duration_ms: 200,
					silence_threshold_db: 16,
					padding_ms: 100,
				},
				detect_job_id: "00000000-0000-0000-0000-000000000050",
				detected_segments: MOCK_SEGMENTS,
				reviewed_cuts: [],
				duration_ms: 30000,
				applied_output_file_id: null,
			},
			transcription: {
				status: "IDLE",
				job_id: null,
				request: null,
				artifact_id: null,
				transcription_id: null,
				reviewed: false,
			},
			captions: {
				status: "IDLE",
				preset_id: null,
				style_config: null,
				render_job_id: null,
				output_file_id: null,
			},
		}

		await page.context().addCookies([
			{
				name: "access_token",
				value: "fake-access-jwt",
				domain: "localhost",
				path: "/",
			},
			{
				name: "refresh_token",
				value: "fake-refresh-jwt",
				domain: "localhost",
				path: "/",
			},
		])

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

		await page.route(`**/api/projects/${PROJECT_ID}/`, async (route) => {
			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify({
					id: PROJECT_ID,
					owner_id: USER_ID,
					name: "Тестовый проект",
					description: null,
					language: "auto",
					folder: null,
					status: "DRAFT",
					workspace_state: null,
					is_active: true,
					created_at: "2025-06-01T00:00:00Z",
					updated_at: "2025-06-01T00:00:00Z",
				}),
			})
		})

		await page.route(`**/api/projects/${PROJECT_ID}/workspace*`, async (route) => {
			if (
				applyStatus === "DONE" &&
				workspace.current_screen === "silence-apply-processing"
			) {
				workspace = {
					...workspace,
					revision: 4,
					phase: "TRANSCRIPTION",
					current_screen: "transcription-settings",
					active_job: null,
					source_file_id: CUT_FILE_ID,
					silence: {
						...workspace.silence,
						status: "APPLIED",
						applied_output_file_id: CUT_FILE_ID,
					},
				}
			}

			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify(workspace),
			})
		})

		await page.route(
			`**/api/projects/${PROJECT_ID}/workflow/actions*`,
			async (route) => {
				const action = route.request().postDataJSON() as Record<string, unknown>
				workflowActions.push(action)

				if (action.type === "SET_SILENCE_CUTS") {
					workspace = {
						...workspace,
						revision: 2,
						silence: {
							...workspace.silence,
							reviewed_cuts: action.cuts as typeof MOCK_SEGMENTS,
						},
					}
				}

				if (action.type === "START_SILENCE_APPLY") {
					workspace = {
						...workspace,
						revision: 3,
						current_screen: "silence-apply-processing",
						active_job: {
							job_id: APPLY_JOB_ID,
							job_type: "SILENCE_APPLY",
						},
						silence: {
							...workspace.silence,
							status: "APPLYING",
						},
					}
				}

				if (action.type === "START_TRANSCRIPTION") {
					workspace = {
						...workspace,
						revision: 5,
						current_screen: "transcription-processing",
						active_job: {
							job_id: TRANSCRIPTION_JOB_ID,
							job_type: "TRANSCRIPTION_GENERATE",
						},
						transcription: {
							...workspace.transcription,
							status: "RUNNING",
							job_id: TRANSCRIPTION_JOB_ID,
							request: action.request as {
								engine: "whisper"
								language?: string
								model: string
							},
						},
					}
				}

				await route.fulfill({
					status: 200,
					contentType: "application/json",
					body: JSON.stringify(workspace),
				})
			},
		)

		await page.route("**/api/files/files/", async (route) => {
			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify([
					{
						id: ORIGINAL_FILE_ID,
						project_id: PROJECT_ID,
						owner_id: USER_ID,
						original_filename: "original-video.mp4",
						path: ORIGINAL_FILE_KEY,
						storage_backend: "S3",
						mime_type: "video/mp4",
						size_bytes: 1024,
						checksum: null,
						file_format: "mp4",
						is_uploaded: true,
						is_deleted: false,
						is_active: true,
						created_at: "2025-06-01T00:00:00Z",
					},
					{
						id: CUT_FILE_ID,
						project_id: PROJECT_ID,
						owner_id: USER_ID,
						original_filename: "cut-video.mp4",
						path: CUT_FILE_KEY,
						storage_backend: "S3",
						mime_type: "video/mp4",
						size_bytes: 1024,
						checksum: null,
						file_format: "mp4",
						is_uploaded: true,
						is_deleted: false,
						is_active: true,
						created_at: "2025-06-01T00:00:00Z",
					},
				]),
			})
		})

		await page.route("**/api/files/files/*/resolve/", async (route) => {
			const fileId = route.request().url().split("/files/")[1]?.split("/")[0]
			const isCutFile = fileId === CUT_FILE_ID

			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify({
					file_id: isCutFile ? CUT_FILE_ID : ORIGINAL_FILE_ID,
					file_url: isCutFile ? CUT_FILE_URL : ORIGINAL_FILE_URL,
					file_path: isCutFile ? CUT_FILE_KEY : ORIGINAL_FILE_KEY,
					filename: isCutFile ? "cut-video.mp4" : "original-video.mp4",
				}),
			})
		})

		await page.route("**/api/files/files/*/", async (route) => {
			const fileId = route.request().url().split("/files/")[1]?.split("/")[0]
			const isCutFile = fileId === CUT_FILE_ID

			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify({
					id: isCutFile ? CUT_FILE_ID : ORIGINAL_FILE_ID,
					project_id: PROJECT_ID,
					owner_id: USER_ID,
					original_filename: isCutFile
						? "cut-video.mp4"
						: "original-video.mp4",
					path: isCutFile ? CUT_FILE_KEY : ORIGINAL_FILE_KEY,
					storage_backend: "S3",
					mime_type: "video/mp4",
					size_bytes: 1024,
					checksum: null,
					file_format: "mp4",
					is_uploaded: true,
					is_deleted: false,
					is_active: true,
					created_at: "2025-06-01T00:00:00Z",
				}),
			})
		})

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

		await page.route("**/api/tasks/status/**", async (route) => {
			const url = route.request().url()

			if (url.includes(APPLY_JOB_ID)) {
				await route.fulfill({
					status: 200,
					contentType: "application/json",
					body: JSON.stringify({
						status: applyStatus,
						job_type: "SILENCE_APPLY",
						progress_pct: applyStatus === "DONE" ? 100 : 30,
						output_data:
							applyStatus === "DONE"
								? {
										file_id: CUT_FILE_ID,
										file_path: CUT_FILE_KEY,
									}
								: null,
					}),
				})
				return
			}

			if (url.includes(TRANSCRIPTION_JOB_ID)) {
				await route.fulfill({
					status: 200,
					contentType: "application/json",
					body: JSON.stringify({
						status: "RUNNING",
						job_type: "TRANSCRIPTION_GENERATE",
						progress_pct: 10,
						output_data: null,
					}),
				})
				return
			}

			await route.fulfill({
				status: 200,
				contentType: "application/json",
				body: JSON.stringify({
					status: "RUNNING",
					progress_pct: 0,
					output_data: null,
				}),
			})
		})

		await page.goto(`/projects/${PROJECT_ID}`)

		await expect(page.locator("[data-testid='FragmentsStep']")).toBeVisible()
		await expect(page.locator("[data-testid='cut-region']")).toHaveCount(2)

		await page.getByRole("button", { name: "Применить" }).click()

		await expect.poll(() => workflowActions.length).toBe(2)

		expect(workflowActions[0]).toMatchObject({
			type: "SET_SILENCE_CUTS",
			revision: 1,
		})
		expect(workflowActions[1]).toMatchObject({
			type: "START_SILENCE_APPLY",
			revision: 2,
		})

		await expect(page.locator("[data-testid='ProcessingStep']")).toBeVisible()

		applyStatus = "DONE"

		await expect(
			page.locator("[data-testid='TranscriptionSettingsStep']"),
		).toBeVisible()

		await page.getByRole("button", { name: "Сгенерировать субтитры" }).click()

		expect(workflowActions[2]).toMatchObject({
			type: "START_TRANSCRIPTION",
			revision: 4,
			request: {
				engine: "whisper",
				model: "base",
			},
		})

		await expect(page.locator("[data-testid='ProcessingStep']")).toContainText(
			"ТРАНСКРИБАЦИЯ",
		)
	})
})
