"use client"

import type { ITranscriptionSettingsStepProps } from "./TranscriptionSettingsStep.d"
import type { JSX } from "react"

import { Info } from "lucide-react"
import { FunctionComponent, useEffect, useState } from "react"
import { Controller, useForm } from "react-hook-form"

import cs from "classnames"

import api from "@shared/api"
import { useWizard } from "@shared/context/WizardContext"
import { useAppSelector } from "@shared/hooks/useAppSelector"
import { Button, CircularProgress, Form, Select, SelectItem } from "@shared/ui"
import { buildCancelJobPayload, useCancelJob } from "../useCancelJob"
import styles from "./TranscriptionSettingsStep.module.scss"

interface ITranscriptionFormData {
	engine: "whisper" | "google" | "salutespeech"
	language: string
	model: string
}

const ENGINE_OPTIONS = [
	{ value: "whisper", label: "Whisper (локальный)" },
	{ value: "google", label: "Google Speech" },
	{ value: "salutespeech", label: "SaluteSpeech" },
]

const LANGUAGE_OPTIONS = [
	{ value: "auto", label: "Авто" },
	{ value: "ru", label: "Русский" },
	{ value: "en", label: "Английский" },
]

const WHISPER_MODEL_OPTIONS = [
	{ value: "base", label: "Базовая" },
	{ value: "small", label: "Малая" },
	{ value: "medium", label: "Средняя" },
	{ value: "large", label: "Большая" },
]

const SALUTE_MODEL_OPTIONS = [
	{ value: "general", label: "Общая" },
	{ value: "finance", label: "Финансы" },
	{ value: "medicine", label: "Медицина" },
]

export const TranscriptionSettingsStep: FunctionComponent<
	ITranscriptionSettingsStepProps
> = ({ className }): JSX.Element => {
	const {
		primaryFileKey,
		activeJobId,
		activeJobType,
		setActiveJob,
		startTranscription,
		goToStep,
	} = useWizard()

	const isProcessing =
		!!activeJobId && activeJobType === "TRANSCRIPTION_GENERATE"

	const [submitError, setSubmitError] = useState<string | null>(null)
	const [isSubmitting, setIsSubmitting] = useState(false)
	const { mutate: cancelJob, isPending: isCancelling } = useCancelJob()

	const { control, handleSubmit, watch, setValue } =
		useForm<ITranscriptionFormData>({
			defaultValues: {
				engine: "whisper",
				language: "auto",
				model: "base",
			},
		})

	const engine = watch("engine")

	useEffect(() => {
		if (engine === "salutespeech") {
			setValue("model", "general")
		} else if (engine === "whisper") {
			setValue("model", "base")
		}
	}, [engine, setValue])

	const onSubmit = async (data: ITranscriptionFormData): Promise<void> => {
		if (!primaryFileKey) return
		setSubmitError(null)
		setIsSubmitting(true)

		try {
			await startTranscription({
				engine: data.engine,
				language: data.language === "auto" ? undefined : data.language,
				model: data.model,
			})
		} catch (error) {
			console.error("Transcription submit failed:", error)
			setSubmitError("Не удалось запустить транскрипцию")
		} finally {
			setIsSubmitting(false)
		}
	}

	/* ---- Processing state (inline) ---- */

	const notification = useAppSelector((state) =>
		activeJobId
			? state.notifications.items.find((n) => n.job_id === activeJobId)
			: null,
	)

	const { data: taskStatus } = api.useQuery(
		"get",
		"/api/tasks/status/{job_id}/",
		{ params: { path: { job_id: activeJobId ?? "" } } },
		{ enabled: isProcessing, refetchInterval: 2000 },
	)

	const progressPct = notification?.progress_pct ?? 0
	const statusMessage =
		notification?.message ?? "Подождите, идёт транскрипция..."
	const isFailed =
		notification?.status === "FAILED" || taskStatus?.status === "FAILED"

	const handleCancel = () => {
		if (isFailed) {
			setActiveJob(null)
			return
		}

		if (!activeJobId || isCancelling) return

		cancelJob(buildCancelJobPayload(activeJobId), {
			onSuccess: () => {
				setActiveJob(null)
			},
		})
	}

	if (isProcessing) {
		return (
			<div
				className={cs(styles.root, className)}
				data-testid="TranscriptionSettingsStep"
			>
				<div className={styles.processingContent}>
					<div className={styles.progressWrapper}>
						<CircularProgress
							percentage={progressPct}
							size={200}
							strokeWidth={8}
							color={isFailed ? "var(--color-danger)" : "var(--color-success)"}
							className={styles.circle}
							bgClassName={styles.circleBg}
							valueClassName={styles.circleValue}
						/>
						<div className={styles.progressInner}>
							<span className={styles.percentage}>
								{Math.round(progressPct)}%
							</span>
							<span className={styles.statusLabel}>
								{isFailed ? "ОШИБКА" : "ТРАНСКРИБАЦИЯ"}
							</span>
						</div>
					</div>

					<p
						className={cs(styles.processingDescription, {
							[styles.descriptionError]: isFailed,
						})}
					>
						{isFailed
							? (notification?.message ?? "Произошла ошибка при транскрипции")
							: statusMessage}
					</p>

					<div className={styles.infoCard}>
						<Info size={16} className={styles.infoIcon} />
						<span>
							Обработка выполняется на сервере. Вы можете покинуть страницу —
							прогресс сохранится.
						</span>
					</div>

					<Button
						variant={isFailed ? "outline" : "danger"}
						size="sm"
						onClick={handleCancel}
						disabled={isCancelling}
					>
						{isFailed
							? "Назад"
							: isCancelling
								? "Отмена..."
								: "Отменить обработку"}
					</Button>
				</div>
			</div>
		)
	}

	/* ---- Settings form ---- */

	return (
		<div
			className={cs(styles.root, className)}
			data-testid="TranscriptionSettingsStep"
		>
			<div className={styles.content}>
				<div className={styles.header}>
					<h2 className={styles.title}>Параметры транскрипции</h2>
					<p className={styles.description}>
						Настройте параметры для генерации субтитров
					</p>
				</div>

				<Form onSubmit={handleSubmit(onSubmit)}>
					<div className={styles.fields}>
						<div className={styles.selectField}>
							<div className={styles.selectLabel}>Движок</div>
							<Controller
								name="engine"
								control={control}
								render={({ field }) => (
									<Select
										value={field.value}
										onValueChange={field.onChange}
										placeholder="Выберите движок"
									>
										{ENGINE_OPTIONS.map((opt) => (
											<SelectItem key={opt.value} value={opt.value}>
												{opt.label}
											</SelectItem>
										))}
									</Select>
								)}
							/>
						</div>

						<div className={styles.selectField}>
							<div className={styles.selectLabel}>Язык</div>
							<Controller
								name="language"
								control={control}
								render={({ field }) => (
									<Select
										value={field.value}
										onValueChange={field.onChange}
										placeholder="Выберите язык"
									>
										{LANGUAGE_OPTIONS.map((opt) => (
											<SelectItem key={opt.value} value={opt.value}>
												{opt.label}
											</SelectItem>
										))}
									</Select>
								)}
							/>
						</div>

						{(engine === "whisper" || engine === "salutespeech") && (
							<div className={styles.selectField}>
								<div className={styles.selectLabel}>Модель</div>
								<Controller
									name="model"
									control={control}
									render={({ field }) => (
										<Select
											value={field.value}
											onValueChange={field.onChange}
											placeholder="Выберите модель"
										>
											{(engine === "whisper"
												? WHISPER_MODEL_OPTIONS
												: SALUTE_MODEL_OPTIONS
											).map((opt) => (
												<SelectItem key={opt.value} value={opt.value}>
													{opt.label}
												</SelectItem>
											))}
										</Select>
									)}
								/>
							</div>
						)}
					</div>

					{submitError && <p className={styles.error}>{submitError}</p>}

					<div className={styles.formFooter}>
						<Button
							type="button"
							variant="outline"
							disabled={isSubmitting}
							onClick={() => goToStep("fragments")}
						>
							Назад
						</Button>
						<Button
							type="submit"
							variant="primary"
							disabled={isSubmitting || !primaryFileKey}
						>
							{isSubmitting ? "Запуск..." : "Сгенерировать субтитры"}
						</Button>
					</div>
				</Form>
			</div>
		</div>
	)
}
