import API_URL from "../../../config/api";
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router";
import type { ApiErrorResponse, Video } from "../../../types";
import styles from "./styles.module.css";
import { LuArrowLeft, LuChevronLeft, LuChevronRight } from "react-icons/lu";
import { Plyr } from "plyr-react";
import "plyr-react/plyr.css";
import { useVideoWatch } from "../../../hooks/useVideoWatch";
import { PiCheckCircleFill } from "react-icons/pi";

export default function Video() {
    const { id } = useParams();
    const [video, setVideo] = useState<Video | null>(null);
    const [error, setError] = useState<ApiErrorResponse | null>(null);
    const [loading, setLoading] = useState(true);
    const [playerReady, setPlayerReady] = useState(false);
    const { watched, markAsWatched } = useVideoWatch(Number(id), video?.watched ?? false);
    const [nextVideo, setNextVideo] = useState<number | null>(null);
    const [previousVideo, setPreviousVideo] = useState<number | null>(null);
    useEffect(() => {
        getVideo();
    }, [id]);

    useEffect(() => {
        if (!video) {
            setPlayerReady(false);
            return;
        }

        setPlayerReady(false);

        const interval = setInterval(() => {
            const videoElement = document.querySelector("video");

            if (!videoElement) return;
            if (videoElement.src.includes("blank.mp4")) return;

            clearInterval(interval);
            setPlayerReady(true);
        }, 300);

        return () => clearInterval(interval);
    }, [video]);

    useEffect(() => {
        if (!playerReady) return;

        let videoElement: HTMLVideoElement | null = null;

        const handleEnded = () => {
            markAsWatched();
        };

        const interval = setInterval(() => {
            const el = document.querySelector("video");

            if (!el) return;
            if (el.src.includes("blank.mp4")) return;

            clearInterval(interval);
            videoElement = el;
            videoElement.addEventListener("ended", handleEnded);
        }, 300);

        return () => {
            clearInterval(interval);
            if (videoElement) {
                videoElement.removeEventListener("ended", handleEnded);
            }
        };
    }, [playerReady, markAsWatched]);

    useEffect(() => {
        if (video?.watched) {
            markAsWatched();
        }
    }, [video, markAsWatched]);

    async function getVideo() {
        setLoading(true);
        setPlayerReady(false);
        setNextVideo(null);
        setPreviousVideo(null);
        setVideo(null);
        try {
            const response = await fetch(`${API_URL}/api/video/${id}`, {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                    Authorization: `Bearer ${localStorage.getItem("token")}`
                },
            });

            const data = await response.json();

            if (response.ok) {
                setVideo(data.data);
                setNextVideo(data.nextVideo as number);
                setPreviousVideo(data.previousVideo as number);
                setError(null);
            } else {
                setVideo(null);
                setError(data as ApiErrorResponse);
            }
        } catch {
            setVideo(null);
            setError({ message: "Erro de ligação" } as ApiErrorResponse);
        } finally {
            setLoading(false);
        }
    }

    const playerSkeleton = (
        <div className={`${styles.playerContent} ${styles.videoPlayerSkeleton}`} aria-hidden="true" />
    );

    const pageSkeleton = (
        <div className="my-3 d-flex flex-column gap-2">
            <div className={`${styles.titleSkeleton} mb-3`} aria-hidden="true" style={{ maxWidth: "1300px", margin: "0 auto" }} />
            <div style={{ maxWidth: "1300px", margin: "0 auto", width: "100%" }}>
                <div className={styles.playerWrapper}>
                    {playerSkeleton}
                </div>
                <div className={styles.descriptionSkeleton} aria-hidden="true" />
                <div className={styles.descriptionSkeletonShort} aria-hidden="true" />
            </div>
        </div>
    );

    return (
        <div className={`${styles.container} p-3 p-xl-0`}>
            <div className="text-start">
                <button className={`${styles.button} border-0 bg-transparent fs-5`}>
                    <Link className={`${styles.link} text-decoration-none`} to="/videos">
                        <LuArrowLeft className={`${styles.LinkIcon} mb-1 fs-4 align-items-center`} />
                        <span className={styles.linkText}>Vídeos</span>
                    </Link>
                </button>
            </div>

            {loading ? (
                pageSkeleton
            ) : video ? (
                <div className="my-3 d-flex flex-column gap-2">
                    <span className={`${styles.title} mb-3`}>{video.title}</span>

                    <div style={{ maxWidth: "1300px", margin: "0 auto", width: "100%" }}>
                        {watched && (
                            <span className="d-block badge text-success text-start fs-6 px-0">
                                <PiCheckCircleFill className="mb-1 me-1" /> Visto
                            </span>
                        )}
                        <div className={styles.playerWrapper}>
                            {!playerReady && playerSkeleton}
                            <div className={`${styles.playerContent} ${playerReady ? "" : styles.playerHidden}`}>
                                <Plyr
                                    source={{
                                        type: "video",
                                        sources: [{ src: `${API_URL}${video.url}`, type: "video/mp4" }],
                                    }}
                                />
                            </div>
                        </div>
                        <div className="d-flex justify-content-between mt-3">
                            {previousVideo && (
                                <Link to={`/video/${previousVideo}`} className={`${styles.previousButton} fs-6 text-start`}><b><LuChevronLeft size={25} title="Vídeo anterior" /> Anterior</b></Link>
                            )}

                            <div></div>

                            {nextVideo && (
                                <Link to={`/video/${nextVideo}`} className={`${styles.nextButton} fs-6 text-end`}><b>Próximo <LuChevronRight size={25} title="Próximo vídeo" /> </b></Link>
                            )}
                        </div>
                        <p className="text-start mt-3 fs-6">{video.description}</p>
                    </div>
                </div>
            ) : (
                <div className="text-center mt-5 d-flex flex-column gap-2 align-items-center">
                    <span className="alert alert-danger">{error?.message}</span>
                </div>
            )}
        </div>
    );
}
