import API_URL from "../../../../config/api";
import { useEffect, useState } from "react";
import { Link } from "react-router";
import type { Category } from "../../../../types";
import styles from "./styles.module.css";
import { LuArrowLeft, LuPlus } from "react-icons/lu";
import { LuUpload } from "react-icons/lu";
import Swal from "sweetalert2";
import { CgSpinner } from "react-icons/cg";
import { motion } from "framer-motion";
import {
    pageTitleTransition,
    pageTitleVariants,
    slideFromBottomTransition,
    slideFromBottomVariants,
    slideFromLeftOnMountTransition,
    slideFromLeftVariants,
} from "../../../../utils/pageMotionVariants";

export default function CreateVideo() {
    const [title, setTitle] = useState<string>("");
    const [description, setDescription] = useState<string>("");
    const [videoFile, setVideoFile] = useState<File | null>(null);
    const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
    const [tags, setTags] = useState<string>("");
    const [isUploading, setIsUploading] = useState(false);
    const [uploadProgress, setUploadProgress] = useState(0);
    const [category_ids, setCategoryIds] = useState<string[]>([]);
    const [creating, setCreating] = useState(false);
    const [categories, setCategories] = useState<Category[]>([]);
    const [order, setOrder] = useState<number>(0);

    useEffect(() => {
        getCategories();
    }, []);

    async function getCategories() {
        const response = await fetch(`${API_URL}/api/categories`, {
            method: "GET",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
        });

        const data = await response.json();

        if (response.ok) {
            setCategories(data.data);
        } else {
            setCategories([]);
        }
    }

    async function createVideo() {
        setCreating(true);

        if (!videoFile || !thumbnailFile || !title || !description) {
            Swal.fire({
                title: "Vídeo e thumbnail são obrigatórios.",
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
            setCreating(false);
            return;
        }

        const formData = new FormData();

        formData.append("title", title);
        formData.append("description", description);
        formData.append("url", videoFile);
        formData.append("thumbnail", thumbnailFile);
        formData.append("tags", tags);
        formData.append("order", order.toString());

        category_ids.forEach(id => {
            formData.append("category_ids[]", id);
        });

        setIsUploading(true);
        setUploadProgress(0);

        const xhr = new XMLHttpRequest();

        xhr.open("POST", `${API_URL}/api/create-video`);
        xhr.setRequestHeader("Authorization", `Bearer ${localStorage.getItem("token")}`);
        xhr.setRequestHeader("Accept", "application/json");
        xhr.upload.onprogress = (event) => {
            if (event.lengthComputable) {
                setUploadProgress(Math.round((event.loaded / event.total) * 100));
            }
        };

        xhr.onload = () => {
            setIsUploading(false);

            let data: any = null;

            try {
                data = xhr.responseText ? JSON.parse(xhr.responseText) : null;
            } catch {
                Swal.fire({
                    title: data.message as string,
                    icon: 'error',
                    showConfirmButton: false,
                    showCloseButton: true,
                });
                return;
            }

            if (xhr.status >= 200 && xhr.status < 300) {
                setUploadProgress(100);
                setIsUploading(false);
                setTitle("");
                setDescription("");
                setVideoFile(null);
                setThumbnailFile(null);
                setTags("");
                setOrder(0);
                setCategoryIds([]);
                setCreating(false);
                Swal.fire({
                    title: data.message as string,
                    icon: 'success',
                    showConfirmButton: false,
                    showCloseButton: true,
                });
            } else {
                setCreating(false);
                setIsUploading(false);
                Swal.fire({
                    title: data.message as string,
                    icon: 'error',
                    showConfirmButton: false,
                    showCloseButton: true,
                });
            }
        };

        xhr.onerror = () => {
            setIsUploading(false);
            setCreating(false);
            Swal.fire({
                title: "Falha de rede durante upload.",
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
        };

        xhr.send(formData);
    }

    function handleCreateCategory() {
        Swal.fire({
            title: 'Criar nova categoria',
            input: 'text',
            inputPlaceholder: 'Categoria...',
            showCancelButton: true,
            confirmButtonText: 'Adicionar',
            cancelButtonText: 'Cancelar',
            confirmButtonColor: 'var(--primary-color)',
            inputValidator: (value) => {
                if (!value) {
                    return 'Indique o nome da categoria!';
                }
            }
        }).then((result) => {
            if (result.isConfirmed) {
                const categoryName = result.value;
                createCategory(categoryName);
            }
        });
    }

    async function createCategory(categoryName: string) {
        const response = await fetch(`${API_URL}/api/categories`, {
            method: "POST",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
            body: JSON.stringify({
                name: categoryName
            })
        });

        const data = await response.json();
        if (response.ok) {
            Swal.fire({
                title: data.message as string,
                icon: 'success',
                showConfirmButton: false,
                showCloseButton: true,
            });
            getCategories();
        } else {
            Swal.fire({
                title: data.message as string,
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
        }
    }

    const handleCheckbox = (e: React.ChangeEvent<HTMLInputElement>) => {
        const { value, checked } = e.target;
        setCategoryIds(prev =>
            checked ? [...prev, value] : prev.filter(id => id !== value)
        );
    };

    return (
        <div className={`${styles.container} p-3 p-xl-0 px-2 px-md-5`}>
            <motion.div variants={slideFromLeftVariants} initial="initial" animate="animate" transition={slideFromLeftOnMountTransition} 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>
            </motion.div>
            <motion.h1 variants={pageTitleVariants} initial="initial" animate="animate" transition={pageTitleTransition} className={styles.title}>Adicionar Vídeo</motion.h1>
            <div>
                <motion.div variants={slideFromBottomVariants} initial="initial" animate="animate" transition={slideFromBottomTransition}>
            <div className="row mx-auto g-4">
                <div className="col-12 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="title">Título</label>
                    <input type="text" className="form-control py-2 text-truncate" id="title" name="title" placeholder="Insira o título do vídeo" value={title} onChange={(e) => setTitle(e.target.value)} required />
                </div>
                <div className="col-12 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="description">Descrição</label>
                    <textarea rows={5} className="form-control py-2" id="description" name="description" placeholder="Insira uma descrição para o vídeo" value={description} onChange={(e) => setDescription(e.target.value)} />
                </div>
                <div className="col-12 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="tags">Palavras-chave <small className="text-muted">(separar por vírgulas)</small></label>
                    <input type="text" className="form-control py-2 text-truncate" id="tags" name="tags" placeholder="Insira as palavras-chave do vídeo" value={tags} onChange={(e) => setTags(e.target.value)} />
                </div>
                <div className="col-12 col-sm-6 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="url">Adicionar vídeo</label>
                    <div className="position-relative">
                        <span className={`${styles.inputFiles} form-control py-2 position-absolute top-0 start-0 text-white px-3 w-100 text-decoration-none text-start fw-light fs-6 text-truncate`}><LuUpload className="mb-1 me-2" /> {videoFile ? videoFile.name : "Carregar vídeo"} </span>
                        <input type="file" className="form-control py-2 text-truncate" id="url" name="url" accept="video/*" style={{ width: '100%', height: '100%', cursor: 'pointer', zIndex: 1000, opacity: 0 }} onChange={(e) => setVideoFile(e.target.files?.[0] ?? null)} />
                    </div>
                </div>
                <div className="col-12 col-sm-6 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="thumbnail">Adicionar thumbnail</label>
                    <div className="position-relative">
                        <span className={`${styles.inputFiles} form-control py-2 position-absolute top-0 start-0 text-white px-3 w-100 text-decoration-none text-start fw-light fs-6 text-truncate`}><LuUpload className="mb-1 me-2" /> {thumbnailFile ? thumbnailFile.name : "Carregar imagem"} </span>
                        <input type="file" className={`${styles.inputFiles} form-control py-2 text-truncate`} id="thumbnail" name="thumbnail" accept="image/*" style={{ width: '100%', height: '100%', cursor: 'pointer', zIndex: 1000, opacity: 0 }} onChange={(e) => setThumbnailFile(e.target.files?.[0] ?? null)} />
                    </div>
                </div>
                <div className="col-12 col-sm-2 px-1 text-start">
                    <label className="form-label fw-bold" htmlFor="order">Ordem</label>
                    <input type="number" className="form-control py-2 text-truncate" id="order" name="order" placeholder="Insira a ordem do vídeo" value={order} onChange={(e) => setOrder(parseInt(e.target.value, 10))} />
                </div>
                <div className="col-12 px-1 text-start">
                    <div className="d-flex">
                        <label className="form-label fw-bold align-content-center mb-0 me-2" htmlFor="category_id">Categorias</label>
                        <button className={`${styles.btnAdicionarCategoria}`} onClick={handleCreateCategory} title="Adicionar categoria"><LuPlus className="mb-1" /></button>
                    </div>
                    <div>
                        {categories && categories.length > 0 ? (
                            categories.map((category) => (
                                <div key={category.id}>
                                    <input type="checkbox" name="category_id" id={`category_${category.id}`} value={category.id} className="me-2" checked={category_ids.includes(category.id.toString())} onChange={handleCheckbox} />
                                    <label htmlFor={`category_${category.id}`} key={category.id}>{category.name}</label>
                                </div>))
                        ) : (
                            <div>
                                <span>Nenhuma categoria encontrada</span>
                            </div>
                        )}

                        {/* <button className={`${styles.btnAdicionarVideo} btn  mt-5`}><LuPlus className="mb-1" /> Nova categoria</button> */}
                    </div>
                </div>
            </div>

            {/*  {error ? (
                <div className="alert alert-danger mt-4">
                    <p className="mb-1">{(error as ApiErrorResponse).message}</p>
                    {Object.keys((error as ApiErrorResponse).errors ?? {}).length > 0 ? (
                        <ul className="mb-0 small">
                            {Object.entries((error as ApiErrorResponse).errors).flatMap(([field, msgs]) =>
                                msgs.map((m) => (
                                    <li key={`${field}-${m}`}>
                                        <strong>{field}</strong>: {m}
                                    </li>
                                ))
                            )}
                        </ul>
                    ) : null}
                </div>
            ) : createVideoResponse?.message || createCategoryResponse?.message ? (
                <div className="alert alert-success mt-4">
                    {createVideoResponse?.message || createCategoryResponse?.message}
                </div>
            ) : null} */}

            {isUploading && (
                <div className="mt-3">
                    <div className="progress" role="progressbar" aria-valuenow={uploadProgress} aria-valuemin={0} aria-valuemax={100}>
                        <div
                            className="progress-bar"
                            style={{ width: `${uploadProgress}%` }}
                        >
                            {uploadProgress}%
                        </div>
                    </div>
                    <small className="text-muted">A carregar vídeo...</small>
                </div>
            )}

            <button type="button" className={`${styles.btnAdicionarVideo} btn btn-primary mt-5`} onClick={() => { createVideo() }} disabled={creating}>{creating ? <CgSpinner className={`${styles.animateSpin} text-2xl fs-3`} /> : <LuPlus />} Adicionar vídeo</button>
                </motion.div>
            </div>
        </div>
    )
}
