"use client"

import type { IConvertMediaViewProps } from "./ConvertMediaView.d"
import type { JSX } from "react"

import { CheckCircle, FileVideo } from "lucide-react"
import { FunctionComponent, useCallback, useEffect, useState } from "react"

import api from "@shared/api"
import { useTaskProgressState } from "@shared/hooks/useTaskProgressState"
import { Button } from "@shared/ui"

import styles from "./ConvertMediaView.module.scss"

const STATUS_IDLE = "idle"
const STATUS_CONVERTING = "converting"
const STATUS_DONE = "done"
const STATUS_FAILED = "failed"

type ConvertStatus =
	| typeof STATUS_IDLE
	| typeof STATUS_CONVERTING
	| typeof STATUS_DONE
	| typeof STATUS_FAILED

const ERROR_CONVERT_FAILED = "Не удалось запустить конвертацию"

function formatNameFromMime(mime: string): string {
	const sub = mime.split("/")[1] ?? mime
	return sub.toUpperCase()
}

export const ConvertMediaView: FunctionComponent<
	IConvertMediaViewProps
> = ({ projectId, fileKey, fileName, mimeType }): JSX.Element => {
	const [status, setStatus] = useState<ConvertStatus>(STATUS_IDLE)
	const [jobId, setJobId] = useState<string | null>(null)
	const [errorMessage, setErrorMessage] = useState<string | null>(null)

	const resolvedProgress = useTaskProgressState({
		jobId,
		enabled: !!jobId && status === STATUS_CONVERTING,
		defaultMessage: "Конвертация...",
	})

	useEffect(() => {
		if (status !== STATUS_CONVERTING) return

		if (resolvedProgress.status === "DONE") {
			setStatus(STATUS_DONE)
			return
		}

		if (resolvedProgress.status === "FAILED") {
			setStatus(STATUS_FAILED)
			setErrorMessage(resolvedProgress.errorMessage ?? ERROR_CONVERT_FAILED)
		}
	}, [resolvedProgress.errorMessage, resolvedProgress.status, status])

	const { mutate, isPending } = api.useMutation(
		"post",
		"/api/tasks/media-convert/",
		{
			onSuccess: (data) => {
				setJobId(data.job_id)
				setStatus(STATUS_CONVERTING)
				setErrorMessage(null)
			},
			onError: () => {
				setErrorMessage(ERROR_CONVERT_FAILED)
			},
		},
	)

	const handleConvert = useCallback(() => {
		mutate({
			body: {
				file_key: fileKey,
				out_folder: "output_files",
				output_format: "mp4",
				project_id: projectId,
			},
		})
	}, [mutate, fileKey, projectId])

	const formatName = formatNameFromMime(mimeType)

	if (status === STATUS_DONE) {
		return (
			<div className={styles.root} data-testid="ConvertMediaView">
				<div className={styles.content}>
					<CheckCircle size={48} className={styles.successIcon} />
					<p className={styles.message}>Конвертация завершена</p>
					<p className={styles.hint}>
						Файл MP4 доступен в разделе «Артефакты»
					</p>
				</div>
			</div>
		)
	}

	if (status === STATUS_CONVERTING) {
		return (
			<div className={styles.root} data-testid="ConvertMediaView">
				<div className={styles.content}>
					<FileVideo size={48} className={styles.icon} />
					<p className={styles.message}>{resolvedProgress.message}</p>
					<div className={styles.progressTrack}>
						<div
							className={styles.progressBar}
							style={{ width: `${resolvedProgress.progressPct}%` }}
						/>
					</div>
					<p className={styles.progressLabel}>
						{Math.round(resolvedProgress.progressPct)}%
					</p>
				</div>
			</div>
		)
	}

	return (
		<div className={styles.root} data-testid="ConvertMediaView">
			<div className={styles.content}>
				<FileVideo size={48} className={styles.icon} />
				<p className={styles.fileName}>{fileName}</p>
				<p className={styles.message}>
					Формат {formatName} не поддерживается для воспроизведения
				</p>
				{errorMessage && (
					<p className={styles.error}>{errorMessage}</p>
				)}
				<Button
					variant="primary"
					onClick={handleConvert}
					disabled={isPending}
				>
					Конвертировать в MP4
				</Button>
			</div>
		</div>
	)
}
