import API_URL from "../../config/api";
import styles from "./styles.module.css";
import { LuUser, LuMenu, LuSearch, LuLogOut, LuUsers, LuMail, LuGraduationCap, LuTvMinimalPlay, LuLayoutDashboard, LuCircleUser, LuPanelLeftClose, LuClock3, LuCalendar } from "react-icons/lu";
import { useEffect, useState } from "react";
import { useNavigate, Link, NavLink } from "react-router";
import { Button, Offcanvas } from "react-bootstrap";
import type { Workshop } from "../../types";
import type { Video } from "../../types";
import { CgSpinner } from "react-icons/cg";
import { useDebounce } from "../../hooks/useDebounce";
import { useGetVideos } from "../../hooks/useGetVideos";
import { useGetVideosSearch } from "../../hooks/useGetVideosSearch";
import { PiCheckCircleFill } from "react-icons/pi";
import { useGetWorkshopsSearch } from "../../hooks/useGetWorkshopsSearch";
import { imageSkeletonFadeStyle, onImageSkeletonLoad } from "../../utils/imageSkeleton";
import { motion, AnimatePresence } from "framer-motion";
import { dropdownTransition, dropdownVariants, slideFromTopTransition, slideFromTopVariants } from "../../utils/pageMotionVariants";
import { useGetCurrentUser } from "../../hooks/useGetCurrentUser";
import AnimatedCounter from "../animatedNumberCount";

export default function Header() {
    const [showMenu, setShowMenu] = useState(false);
    const [showSearch, setShowSearch] = useState(false);
    const [search, setSearch] = useState("");
    const [loading, setLoading] = useState(false);
    const [searchCompleted, setSearchCompleted] = useState(false);
    const [videosSearched, setVideosSearched] = useState<Video[]>([]);
    const [workshopsSearched, setWorkshopsSearched] = useState<Workshop[]>([]);
    const debouncedSearch = useDebounce(search, 500);
    const [showDropdown, setShowDropdown] = useState(false);
    const { getVideos } = useGetVideos();
    const { getVideosSearch } = useGetVideosSearch();
    const { getWorkshopsSearch } = useGetWorkshopsSearch();
    const { getCurrentUser } = useGetCurrentUser();
    const [videosWatched, setVideosWatched] = useState(0);
    const [videosCount, setVideosCount] = useState(0);
    const [role, setRole] = useState(0);
    
    const navigate = useNavigate();

    useEffect(() => {
        const fetchCurrentUser = async () => {
            const currentUser = await getCurrentUser();
            setRole(currentUser.data.role_id);
            setVideosWatched(currentUser.data.videosWatched);
            setVideosCount(currentUser.data.videosCount);
        };
        fetchCurrentUser();
    }, []);

    const handleCloseMenu = () => setShowMenu(false);
    const handleShowMenu = () => setShowMenu(true);
    const handleCloseSearch = () => setShowSearch(false);
    const handleShowSearch = () => setShowSearch(true);

    useEffect(() => {

        if (debouncedSearch.trim() === "") {
            setVideosSearched([]);
            setWorkshopsSearched([]);
            setLoading(false);
            setSearchCompleted(false);
            return;
        }

        setLoading(true);
        setSearchCompleted(false);

        const fetchAll = async () => {

            try {

                const [_videosData, videosSearchedData, workshopsData] = await Promise.all([
                    getVideos({ page: 1 }),
                    getVideosSearch(debouncedSearch),
                    getWorkshopsSearch(debouncedSearch),
                ]);

                if ("videos" in videosSearchedData) {
                    setVideosSearched(videosSearchedData.videos);
                } else {
                    setVideosSearched([]);
                }

                if ("workshops" in workshopsData) {
                    setWorkshopsSearched(workshopsData.workshops);
                } else {
                    setWorkshopsSearched([]);
                }

                setSearchCompleted(true);

            } catch (e) {

                setVideosSearched([]);
                setWorkshopsSearched([]);
                setSearchCompleted(true);

            } finally {
                setLoading(false);
            }
        };

        fetchAll();

    }, [debouncedSearch]);

    function handleSearch(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        const q = search.trim();

        if (q === "") {
            setShowSearch(false);
            return;
        }

        navigate(`/search?q=${encodeURIComponent(q)}`);
        setShowSearch(false);
    }

    return (
        <header className={`${styles.header} d-flex justify-content-between justify-content-xl-end align-items-center ps-4`} >

            <>
                <button type="button" className={`${styles.sidebarOpen} align-items-center justify-content-center d-xl-none`} onClick={handleShowMenu}>
                    <LuMenu size={30} />
                </button>

                <Offcanvas show={showMenu} onHide={handleCloseMenu} responsive="xl" className="d-xl-none">
                    <Offcanvas.Header >
                        <Offcanvas.Title className={"w-100 d-flex justify-content-between"}>
                            <Link className={`${styles.logoLink} justify-content-start`} to="/dashboard">
                                <img
                                    className={styles.logo}
                                    src="/src/assets/logo.png"
                                    alt="Logo"
                                    onClick={handleCloseMenu}
                                />
                            </Link>
                            <button type="button" className={`${styles.sidebarClose} align-items-center justify-content-center d-xl-none`} onClick={handleCloseMenu}> <LuPanelLeftClose size={24} /> </button>
                        </Offcanvas.Title>
                    </Offcanvas.Header>

                    <Offcanvas.Body className="d-flex flex-column">
                        <nav className={`${styles.nav} flex-grow-1`}>
                            <ul className={styles.navList}>
                                <li className={`${styles.navItem} text-start`}>
                                    <NavLink className={styles.navLink} to="/dashboard" onClick={handleCloseMenu}> <LuLayoutDashboard className="me-2" size={24} />Dashboard</NavLink>
                                </li>
                                <li className={`${styles.navItem} text-start`}>
                                    <NavLink className={styles.navLink} to="/videos" onClick={handleCloseMenu}> <LuTvMinimalPlay className="me-2" size={24} />Videos</NavLink>
                                </li>
                                <li className={`${styles.navItem} text-start`}>
                                    <NavLink className={styles.navLink} to="/workshops" onClick={handleCloseMenu}> <LuGraduationCap className="me-2" size={24} />Workshops</NavLink>
                                </li>
                                {role === 1 && (
                                    <li className={`${styles.navItem} text-start`}>
                                        <NavLink className={styles.navLink} to="/admin/users" onClick={handleCloseMenu}> <LuUsers className="me-2" size={24} />Utilizadores</NavLink>
                                    </li>
                                )}
                                <li className={`${styles.navItem} text-start`}>
                                    <NavLink className={styles.navLink} to="/contactos" onClick={handleCloseMenu}> <LuMail className="me-2" size={24} />Contactos</NavLink>
                                </li>
                            </ul>
                        </nav>

                        {role !== 1 && videosCount > 0 && (
                            <div className="d-flex d-sm-none justify-content-center">
                                <span className="fw-semibold">Vídeos assistidos</span>
                                <span className={`${styles.badge} badge align-content-center ms-3`}><AnimatedCounter value={videosWatched} />/<AnimatedCounter value={videosCount} /></span>
                            </div>
                        )}

                        <div className={`${styles.logoutWrapper} text-center`}>
                            <Link className={styles.logoutButton} to="/logout"> <LuLogOut className="me-2" size={24} />Logout</Link>
                        </div>
                    </Offcanvas.Body>
                </Offcanvas>
            </>

            <nav className="navbar px-3">
                <div className={styles.headerRight}>
                    {role !== 1 && videosCount > 0 && (
                        <>
                            <div className="d-none d-sm-flex align-items-center gap-1 text-muted">
                                <span className="fw-semibold">Vídeos assistidos</span>
                                <span className={`${styles.badge} badge align-content-center`}><AnimatedCounter value={videosWatched} />/<AnimatedCounter value={videosCount} /></span>
                            </div>
                        </>
                    )}

                    <div className="">
                        <Button className={`${styles.searchButton} me-2`} variant="link" onClick={handleShowSearch}>
                            <LuSearch size={30} />
                        </Button>
                        <Offcanvas show={showSearch} onHide={handleCloseSearch} placement="top" style={{ height: "fit-content" }}>
                            <Offcanvas.Header className={`${styles.offcanvasHeader} position-relative d-flex flex-column py-4 text-start`} closeButton>
                                <Offcanvas.Title className="align-self-start mb-3">Efetuar pesquisa</Offcanvas.Title>
                                <form onSubmit={handleSearch} className="mb-0 w-100">
                                    <div className="input-group mb-2">
                                        <input type="text" className="form-control border-1" placeholder="Digite para pesquisar"
                                            value={search}
                                            onChange={(e) => {
                                                setSearch(e.target.value);
                                            }} />
                                        <button type="submit" className="btn btn-primary">Pesquisar</button>
                                    </div>

                                </form>
                            </Offcanvas.Header>
                            <Offcanvas.Body className="py-0">
                                {loading ? (
                                    <div className="d-flex align-items-center gap-2 my-3">
                                        <CgSpinner className={`${styles.animateSpin} text-2xl fs-3`} />
                                        <span>A procurar...</span>
                                    </div>

                                ) : (
                                    <>
                                        {(videosSearched.length > 0 || workshopsSearched.length > 0) && searchCompleted ? (
                                            <>

                                                {videosSearched.length > 0 ? (
                                                    <motion.div variants={slideFromTopVariants} initial="initial" animate="animate" transition={slideFromTopTransition} className="d-flex flex-column">
                                                        <span className="fs-1 text-center fw-bold mb-1 mt-3">Vídeos</span>

                                                        <div className="row">
                                                            {videosSearched.length > 0 && (
                                                                <span className="text-muted text-start d-block">Vídeos encontrados: <AnimatedCounter value={videosSearched.length} /></span>
                                                            )}

                                                            {videosSearched.map((video) => (
                                                                <div className="col-12 col-sm-6 col-lg-4 col-xl-3 p-2">
                                                                    <Link to={`/video/${video.id}`} className={`${styles.linkVideo} text-decoration-none text-black pb-2`} key={video.id} onClick={handleCloseSearch}>
                                                                        <div className={`${styles.boxVideo} position-relative`} >
                                                                            <img
                                                                                className={`${styles.videoThumbnail} position-absolute top-0 start-0 bottom-0 h-100`}
                                                                                src={`${API_URL}/storage/${video.thumbnail}`}
                                                                                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} 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>
                                                                </div>
                                                            ))}

                                                        </div>
                                                    </motion.div>

                                                ) : null}

                                                {workshopsSearched.length > 0 ? (
                                                    <motion.div variants={slideFromTopVariants} initial="initial" animate="animate" transition={slideFromTopTransition} className="d-flex flex-column">
                                                        <span className="fs-1 text-center fw-bold mb-1 mt-3">Workshops</span>
                                                        <div className="row g-3 mb-3">
                                                            {workshopsSearched.length > 0 && (
                                                                <span className="text-muted text-start d-block">Workshops encontrados: {workshopsSearched.length}</span>
                                                            )}
                                                            {workshopsSearched.map((workshop) => (
                                                                <div className="col-12 col-sm-6 col-lg-4 col-xl-3 mt-0 p-2 position-relative">
                                                                    <div className={`${styles.boxWorkshop} text-start pb-3`}>
                                                                        <Link to={`/workshop/${workshop.id}`} className="text-decoration-none text-black" onClick={handleCloseSearch}>
                                                                            <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}`}><LuCalendar className={`${styles.icon} mb-1 me-2`} />{workshop.date.split('-').reverse().join('-')}</p>
                                                                                    <p className={`${styles.timeWorkshop}`}><LuClock3 className={`${styles.icon} mb-1 me-2`} />{workshop.time_start.slice(0, 5)} - {workshop.time_end.slice(0, 5)}</p>
                                                                                </div>
                                                                            </div>
                                                                            <div className="px-3">
                                                                                <h2 className={`${styles.titleWorkshop} d-block text-start mt-3`}>{workshop.title}</h2>
                                                                                <div className="position-relative d-flex flex-column d-md-none d-xl-flex d-xxl-none mt-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>
                                                                            <button type="button" className={`${styles.linkWorkshop} btn text-center mt-3 py-2 px-5 mx-auto text-decoration-none`}>
                                                                                Detalhes
                                                                            </button>
                                                                        </Link>
                                                                    </div>
                                                                </div>


                                                            ))}

                                                        </div>
                                                    </motion.div>
                                                ) : null}
                                            </>

                                        ) : (videosSearched.length === 0 && workshopsSearched.length === 0) && searchCompleted ? (
                                            <div className="d-flex flex-column">
                                                <span className="text-muted text-start my-3">Sem resultados</span>
                                            </div>
                                        ) : null}
                                    </>
                                )}

                            </Offcanvas.Body>
                        </Offcanvas>
                    </div>

                    <div className="btn-group" onMouseEnter={() => setShowDropdown(true)} onMouseLeave={() => setShowDropdown(false)}>
                        <button type="button" className={`${styles.headerDropdownToggle} btn dropdown-toggle`} >
                            <LuUser size={30} />
                        </button>

                        <AnimatePresence>
                            {showDropdown && (
                                <motion.ul
                                    variants={dropdownVariants}
                                    initial="initial"
                                    animate="animate"
                                    exit="exit"
                                    transition={dropdownTransition}
                                    className="dropdown-menu dropdown-menu-end"
                                    style={{ display: "block", zIndex: 2000, right: 0, top: "100%", marginTop: "0.25rem" }}>
                                    <li><Link className="dropdown-item" to="/profile"><LuCircleUser className="mb-1 me-2" size={24} />A minha conta</Link></li>
                                    <li><Link className="dropdown-item mt-2" to="/logout" style={{ color: "var(--text-primary-color)" }}> <LuLogOut className="mb-1 me-2" size={24} />Sair</Link></li>
                                </motion.ul>
                            )}
                        </AnimatePresence>
                    </div>
                </div>
            </nav>
        </header >
    );
}