import API_URL from "../../../config/api";
import { useEffect, useState } from "react";
import type { User, Video, Workshop } from "../../../types";
import styles from "./styles.module.css";
import { LuCheck, LuKeyRound, LuPencil, LuX, LuArrowUpRight, LuClock3, LuCalendar } from "react-icons/lu";
import { CgSpinner } from "react-icons/cg";
import { Link } from "react-router";
import AnimatedProgressBar from "../../../components/animatedProgressBar";
import AnimatedCounter from "../../../components/animatedNumberCount";
import { imageSkeletonFadeStyle, onImageSkeletonLoad } from "../../../utils/imageSkeleton";
import { PiCheckCircleFill } from "react-icons/pi";
import Swal from "sweetalert2";
import { motion } from "framer-motion";
import {
    cardInViewTransition,
    cardInViewVariants,
    pageTitleTransition,
    pageTitleVariants,
    slideFromBottomInViewTransition,
    slideFromBottomVariants,
    slideFromLeftTransitionNoDelay,
    slideFromLeftVariants,
    slideFromRightTransition,
    slideFromRightVariants,
    slideFromTopTransition,
    slideFromTopTransitionDelayed,
    slideFromTopVariants,
    viewportOnce,
} from "../../../utils/pageMotionVariants";

export default function Profile() {
    const [role, setRole] = useState(0);
    const [userId, setUserId] = useState(0);
    const [loading, setLoading] = useState(true);

    const [formEdit, setFormEdit] = useState<boolean>(false);
    const [formEditPassword, setFormEditPassword] = useState<boolean>(false);
    const [userData, setUserData] = useState<User | null>(null);
    const [workshops, setWorkshops] = useState<Workshop[]>([]);
    const [workshopsCount, setWorkshopsCount] = useState(0);
    const [nextWorkshops, setNextWorkshops] = useState<Workshop[]>([]);
    const [videos, setVideos] = useState<Video[]>([]);
    const [videosCount, setVideosCount] = useState(0);
    const [videosWatched, setVideosWatched] = useState(0);
    const [progressoVideos, setProgressoVideos] = useState(0);

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

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

        const data = await response.json();

        setUserData(data.data as User);
        setWorkshops(data.workshopsInscribed as Workshop[]);
        setWorkshopsCount(data.workshopsCount);
        setVideos(data.videos as Video[]);
        setVideosCount(data.videosCount);
        setNextWorkshops(data.nextWorkshops as Workshop[]);
        setVideosWatched(data.videosWatched);
        setUserId(data.userId);
        setRole(data.role);
        setProgressoVideos(Math.round(data.videosWatched / data.videosCount * 100));
        setLoading(false);
    };

    async function updatePassword(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        const user_id = userData?.id;
        const passwordAtual = formData.get("passwordAtual");
        const novaPassword = formData.get("novaPassword");
        const confirmarPassword = formData.get("confirmarPassword");

        if (novaPassword !== confirmarPassword) {
            Swal.fire({
                title: "As passwords não coincidem",
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
            return;
        }

        const payload = {
            user_id: user_id,
            passwordAtual: passwordAtual,
            novaPassword: novaPassword,
            confirmarPassword: confirmarPassword,
        };

        const response = await fetch(`${API_URL}/api/profile/${user_id}`, {
            method: "PATCH",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
            body: JSON.stringify(payload),
        });

        const data = await response.json();

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

    async function update(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        const user_id = userData?.id;
        const name = formData.get("name") || userData?.name;
        const email = formData.get("email") || userData?.email;

        const payload = {
            user_id: user_id,
            name: name,
            email: email,
        };

        const response = await fetch(`${API_URL}/api/profile/${user_id}`, {
            method: "PATCH",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
            body: JSON.stringify(payload),
        });

        const data = await response.json();

        if (response.ok) {
            setFormEdit(false);
            Swal.fire({
                title: data.message,
                icon: 'success',
                showConfirmButton: false,
                showCloseButton: true,
            });
            getProfile();
        } else {
            Swal.fire({
                title: data.message,
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
        }
    }

    /* Cancelar inscrição num workshop */
    async function cancelarInscricao(workshopId: number) {
        const response = await fetch(`${API_URL}/api/cancelar-inscricao/${workshopId}`, {
            method: "DELETE",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
        });

        const data = await response.json();

        if (response.ok) {
            Swal.fire({
                title: data.message,
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
            getProfile();
            setWorkshops(data.workshops as Workshop[]);
        } else {
            Swal.fire({
                title: data.message,
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: true,
            });
        }
    }

    if (loading) {
        return (
            <div className="text-center mt-5 d-flex flex-column gap-2 align-items-center">
                <CgSpinner className={`${styles.animateSpin} text-2xl fs-3`} />
            </div>
        );
    }

    return (
        <div className="container">
            <motion.h1 variants={pageTitleVariants} initial="initial" animate="animate" transition={pageTitleTransition} className={styles.title}>Os meus dados</motion.h1>
            <div>
                <div className="my-3">
                    <div className="row mt-5 justify-content-between">
                        <motion.div variants={slideFromLeftVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={slideFromLeftTransitionNoDelay} className="col-12 col-lg-8 p-3 rounded-3">
                            <div className={`${styles.userCard} p-4 bg-white h-100`}>
                                <div className="row justify-content-between">
                                    <div className="col-12 d-flex text-start mt-xl-0 justify-content-between flex-grow-1 mb-3">
                                        <div className="d-flex flex-column">
                                            <span className="fw-bold fs-4 mt-1">{userData?.name}</span>
                                            <span className="fs-5 flex-grow-1">{userData?.email}</span>
                                        </div>
                                    </div>
                                    <div className="col-12 d-flex flex-column flex-md-row gap-0 gap-md-2 text-end align-items-start align-items-md-end mt-md-0 mx-auto mx-md-0 flex-wrap">
                                        <span className="d-flex justify-content-center flex-wrap flex-sm-nowrap border border-secondary-subtle py-2 px-2 rounded-3 fs-6 fw-medium py-0" style={{ maxWidth: "fit-content", height: "fit-content" }}>Membro desde: <b className="fw-bold fs-6">{new Date(userData?.created_at as string).toLocaleDateString('pt-PT')}</b></span>
                                        <div className="d-flex flex-wrap flex-grow-1 justify-content-evenly justify-content-md-end flex-wrap mt-3 mx-auto">
                                            <a className={`${styles.updateButton} text-decoration-none text-primary text-center px-3`} onClick={() => { setFormEdit(true); setFormEditPassword(false); }}> Editar <LuPencil className={`${styles.icon} mb-1 text-primary`} /></a>
                                            <a className={`${styles.passwordButton} text-decoration-none text-danger px-1 px-md-3
                                            `} onClick={() => { setFormEditPassword(true); setFormEdit(false); }}> Alterar password <LuKeyRound className={`${styles.icon} mb-1 text-danger`} /></a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </motion.div>
                        <motion.div variants={slideFromRightVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={slideFromRightTransition} className="col-12 col-lg-4 p-3">
                            {role === 1 ? (
                                <div className={`${styles.userVideosWatched} text-start d-flex flex-column h-100 gap-3 p-4`}>
                                    <div className="d-flex flex-column">
                                        <span className="fw-normal fs-6" style={{ color: "var(--bg-grey)" }}>Vídeos ativos</span>
                                        <span className="fs-2 fw-bold text-white"><AnimatedCounter value={videosCount} /></span>
                                    </div>
                                    <div className="d-flex flex-column">
                                        <span className="fw-normal fs-6" style={{ color: "var(--bg-grey)" }}>Workshops agendados</span>
                                        <span className="fs-2 fw-bold text-white"><AnimatedCounter value={workshopsCount} /></span>
                                    </div>
                                </div>
                            ) : (
                                <div className={`${styles.userVideosWatched} text-start d-flex flex-column h-100 gap-3 p-4`}>
                                    <div className="d-flex flex-column">
                                        <span className="fw-normal fs-6" style={{ color: "var(--bg-grey)" }}>Vídeos assistidos</span>
                                        <span className="fs-2 fw-bold text-white"><AnimatedCounter value={videosWatched} />/<AnimatedCounter value={videosCount} /></span>
                                    </div>

                                    <div className="d-flex flex-column">
                                        <span className="fw-normal fs-6" style={{ color: "var(--bg-grey)" }}>Workshops inscrito</span>
                                        <span className="fs-2 fw-bold text-white"><AnimatedCounter value={workshopsCount} /></span>
                                    </div>
                                </div>
                            )}
                        </motion.div>
                    </div>
                </div>
            </div>

            {formEdit ? (
                <motion.div variants={slideFromTopVariants} initial="initial" whileInView="animate" transition={slideFromTopTransition} className={`${styles.containerForm} my-3 px-2 p-sm-4`}>
                    <span className={styles.title}>Editar dados</span>

                    <form method="patch" onSubmit={update} id="formEditUser">
                        <div className="row g-3 mt-2">
                            <input type="hidden" name="user_id" value={userId} />
                            <div className="col-12 col-md-6 text-start">
                                <label className="form-label fw-bold" htmlFor="name">Nome</label>
                                <input type="text" className="form-control py-2" id="name" name="name" defaultValue={userData?.name} />
                            </div>
                            <div className="col-12 col-md-6 text-start">
                                <label className="form-label fw-bold" htmlFor="email">Email</label>
                                <input type="email" className="form-control py-2" id="email" name="email" defaultValue={userData?.email} />
                            </div>
                        </div>

                        <div className="buttonsContainer mt-5 d-flex gap-2 justify-content-center flex-wrap" >
                            <button type="button" className={`${styles.closeFormButton}`} onClick={() => setFormEdit(false)}> Cancelar <LuX className={`${styles.icon} mb-1`} /></button>
                            <button type="submit" className={`${styles.submitFormButton}`} >Submeter dados <LuCheck className="mb-1" /></button>
                        </div>
                    </form>
                </motion.div>
            ) : formEditPassword ? (
                <motion.div variants={slideFromTopVariants} initial="initial" whileInView="animate" transition={slideFromTopTransitionDelayed} className={`${styles.containerForm} my-3 px-2 p-sm-4`}>
                    <span className={styles.title}>Alterar password</span>

                    <form method="patch" onSubmit={updatePassword} id="formEditPassword">
                        <div className="row g-3 mt-2">
                            <input type="hidden" name="user_id" value={userId} />
                            <div className="col-12 col-lg-4 text-start">
                                <label className="form-label fw-bold" htmlFor="passwordAtual">Password atual</label>
                                <input type="password" className="form-control py-2" id="passwordAtual" name="passwordAtual" />
                            </div>
                            <div className="col-12 col-sm-6 col-lg-4 text-start">
                                <label className="form-label fw-bold" htmlFor="novaPassword">Nova password</label>
                                <input type="password" className="form-control py-2" id="novaPassword" name="novaPassword" />
                            </div>
                            <div className="col-12 col-sm-6 col-lg-4 text-start">
                                <label className="form-label fw-bold" htmlFor="confirmarPassword">Confirmar password</label>
                                <input type="password" className="form-control py-2" id="confirmarPassword" name="confirmarPassword" />
                            </div>
                        </div>

                        <div className="buttonsContainer mt-4 d-flex gap-2 justify-content-center" >
                            <button type="button" className={`${styles.closeFormButton}`} onClick={() => setFormEditPassword(false)}> Cancelar <LuX className={`${styles.icon} mb-1`} /></button>
                            <button type="submit" className={`${styles.submitFormButton}`} >Submeter dados <LuCheck className="mb-1" /></button>
                        </div>
                    </form>
                </motion.div>
            ) : null}

            <motion.div variants={slideFromBottomVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={slideFromBottomInViewTransition} className={`${styles.containerVideos} mt-4 px-2 p-sm-4 mx-1`}>
                <div className="d-flex flex-column flex-sm-row justify-content-between align-items-center px-0" >
                    <h2 className={`${styles.subtitle} text-center text-sm-start mt-4 mt-sm-3 mb-4 px-0 `}>{role === 1 ? "Vídeos ativos" : "Continuar Formação"}</h2>
                    <Link to="/videos" className={`${styles.link} text-decoration-none fw-semibold fs-5 mt-sm-3 mb-4`}>Ver vídeos <LuArrowUpRight className="mb-1 me-2" size={25} /></Link>
                </div>

                {role !== 1 && (
                    <>
                        <AnimatedProgressBar value={progressoVideos ?? 0} className={`${styles.progressBar}`} />

                        {progressoVideos === 100 && (
                            <div className="text-center mt-3">
                                <span className="text-black fw-bold fs-6">Parabéns! A sua formação está completa!</span>
                            </div>
                        )}
                    </>
                )}

                <div className="row mt-4 px-2">
                    {videosCount > 0 ? videos.map((video: Video) => (
                        <motion.div key={video.id} variants={cardInViewVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={cardInViewTransition} className="col-12 col-sm-6 col-lg-4 p-2">
                            <Link to={`/video/${video.id}`} className={`${styles.linkVideo} text-decoration-none text-black`}>
                                <div className={`${styles.boxVideo} position-relative`} data-category={video.categories?.map((category) => category.id).join(', ')} >
                                    {role === 1 && (
                                        <Link to={`/admin/edit-video/${video.id}`}> <LuPencil className={`${styles.iconEdit} text-decoration-none`} /> </Link>
                                    )}
                                    <img
                                        src={`${API_URL}/storage/${video.thumbnail}`}
                                        className={`${styles.videoThumbnail} position-absolute top-0 start-0 bottom-0 h-100`}
                                        alt={video.title}
                                        style={imageSkeletonFadeStyle}
                                        onLoad={onImageSkeletonLoad}
                                    />
                                    <div className={`${styles.boxVideoInfo} px-3 py-2 text-start text-truncate position-absolute bottom-0`}>
                                        <h2 className={`${styles.titleVideo} d-flex text-wrap mb-1`}>{video.title}</h2>
                                    </div>
                                    {video.watched && <span className="d-block badge text-success text-start fs-6 position-absolute top-0 start-0 bg-success-subtle text-success px-3 py-2" style={{ borderRadius: "0 0 var(--border-radius) 0" }}><PiCheckCircleFill className="mb-1 me-1" /> Visto</span>}
                                </div>
                            </Link>
                        </motion.div>
                    )) : videosCount === 0 ? (
                        <div className="col-12 text-start ps-1">
                            <span className="text-muted fs-5">Nenhum vídeo encontrado</span>
                        </div>
                    ) : null}
                </div>
            </motion.div>

            <div className="ms-0 px-lg-4 mt-4">
                <motion.div variants={cardInViewVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={cardInViewTransition} className="d-flex flex-column flex-sm-row justify-content-between align-items-center px-0" >
                    <h2 className={`${styles.subtitle} text-center text-sm-start mt-4 mt-sm-3 mb-4`}>{role === 1 ? "Workshops agendados" : "Workshops Inscrito"}</h2>
                    <Link to="/workshops" className={`${styles.link} text-decoration-none fw-semibold fs-5 mt-sm-3 mb-sm-4`}>Ver workshops <LuArrowUpRight className="mb-1 me-2" size={25} /></Link>
                </motion.div>
                <div className="row mt-4 mt-sm-1 px-2 mb-5">
                    {role !== 1 && workshopsCount > 0 ? workshops.map((workshop: Workshop) => (
                        <motion.div key={workshop.id} variants={cardInViewVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={cardInViewTransition} className="col-12 col-sm-6 col-lg-4 p-2 position-relative">
                            <div className={`${styles.boxWorkshop} d-flex flex-column text-start pb-3 h-100`}>
                                <div className={`${styles.thumbnailWorkshop} position-relative`}>
                                    <img
                                        src={`${API_URL}/storage/${workshop.image}`}
                                        alt={workshop.title}
                                        className={styles.thumbnailWorkshop}
                                        style={imageSkeletonFadeStyle}
                                        onLoad={onImageSkeletonLoad}
                                    />
                                    <div className="position-absolute w-100 bottom-0 justify-content-evenly d-none d-md-flex d-xl-none d-xxl-flex mb-2">
                                        <p className={`${styles.dateWorkshop} px-1`}><LuCalendar className={`${styles.icon} mb-1 me-1`} />{workshop.date.split('-').reverse().join('-')}</p>
                                        <p className={`${styles.timeWorkshop} px-1`}> <LuClock3 className={`${styles.icon} mb-1 me-1`} />{workshop.time_start.slice(0, 5)} -  {workshop.time_end.slice(0, 5)}</p>
                                    </div>
                                </div>
                                    <h2 className={`${styles.titleWorkshop} d-block text-start mt-3 px-3 flex-grow-1 mb-0`}>{workshop.title}</h2>
                                    <div className="position-relative d-flex flex-column d-md-none d-xl-flex d-xxl-none mt-3 px-3">
                                        <span className={`${styles.dateWorkshopMobile} text-start mb-1`}><LuCalendar className={`${styles.icon} mb-1 me-2`} />{workshop.date.split('-').reverse().join('-')}</span>
                                        <span className={`${styles.timeWorkshopMobile} text-start`}><LuClock3 className={`${styles.icon} mb-1 me-2`} />{workshop.time_start.slice(0, 5).split(':').join('h')} -  {workshop.time_end.slice(0, 5).split(':').join('h')}</span>
                                    </div>
                                <div className="d-flex flex-wrap justify-content-evenly px-3 gap-2 mt-3">
                                    <Link to={`${role === 1 ? `/admin/edit-workshop/${workshop.id}` : `/workshop/${workshop.id}`}`} className={`${styles.linkWorkshop} d-block text-center py-2 px-5 text-decoration-none`}> Detalhes </Link>

                                    {role !== 1 ? (
                                        <button type="button" className={`${styles.btncancelarInscricao} btn text-center py-2  text-decoration-none`} onClick={() => cancelarInscricao(workshop.id)}>
                                            Anular inscrição
                                        </button>
                                    ) : null}
                                </div>
                            </div>
                        </motion.div>
                    )
                    ) : workshopsCount === 0 ? (
                        <div className="col-12 text-center px-0 mt-3">
                            <span className="text-black text-muted fs-5 mb-5">Não está inscrito em nenhum workshop</span>
                        </div>
                    ) : null}

                    {role === 1 && workshopsCount > 0 ? nextWorkshops.map((workshop: Workshop) => (
                        <motion.div key={workshop.id} variants={cardInViewVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={cardInViewTransition} className="col-12 col-sm-6 col-lg-4 p-2 position-relative">
                            <div className={`${styles.boxWorkshop} d-flex flex-column text-start pb-3 h-100`}>
                                <div className={`${styles.thumbnailWorkshop} position-relative`}>
                                    <img
                                        src={`${API_URL}/storage/${workshop.image}`}
                                        alt={workshop.title}
                                        className={styles.thumbnailWorkshop}
                                        style={imageSkeletonFadeStyle}
                                        onLoad={onImageSkeletonLoad}
                                    />
                                    <div className="position-absolute w-100 bottom-0 justify-content-evenly d-none d-md-flex d-xl-none d-xxl-flex mb-2">
                                        <p className={`${styles.dateWorkshop} px-1`}><LuCalendar className={`${styles.icon} mb-1 me-1`} />{workshop.date.split('-').reverse().join('-')}</p>
                                        <p className={`${styles.timeWorkshop} px-1`}> <LuClock3 className={`${styles.icon} mb-1 me-1`} />{workshop.time_start.slice(0, 5)} -  {workshop.time_end.slice(0, 5)}</p>
                                    </div>
                                </div>
                                    <h2 className={`${styles.titleWorkshop} d-block text-start mt-3 px-3 flex-grow-1 mb-0`}>{workshop.title}</h2>
                                    <div className="position-relative d-flex flex-column d-md-none d-xl-flex d-xxl-none mt-3 px-3">
                                        <span className={`${styles.dateWorkshopMobile} text-start mb-1`}><LuCalendar className={`${styles.icon} mb-1 me-2`} />{workshop.date.split('-').reverse().join('-')}</span>
                                        <span className={`${styles.timeWorkshopMobile} text-start`}><LuClock3 className={`${styles.icon} mb-1 me-2`} />{workshop.time_start.slice(0, 5).split(':').join('h')} -  {workshop.time_end.slice(0, 5).split(':').join('h')}</span>
                                    </div>
                                <div className="d-flex flex-wrap justify-content-evenly px-3 gap-2 mt-3">
                                    <Link to={`${role === 1 ? `/admin/edit-workshop/${workshop.id}` : `/workshop/${workshop.id}`}`} className={`${styles.linkWorkshop} d-block text-center py-2 px-5 text-decoration-none`}> Detalhes </Link>
                                </div>
                            </div>
                        </motion.div>
                    )
                    ) : workshopsCount === 0 ? (
                        <div className="col-12 text-center px-0 mt-3">
                            <span className="text-black text-muted fs-5 mb-5">Não há workshops agendados</span>
                        </div>
                    ) : null}
                </div>
            </div>


        </div>
    );
}