import API_URL from "../../../../config/api";
import { useEffect, useState } from "react";
import { useDebounce } from "../../../../hooks/useDebounce";
import type { ApiErrorResponse, User } from "../../../../types";
import { Link } from "react-router";
import styles from "./styles.module.css";
import { LuPencil, LuSettings2, LuPlus } from "react-icons/lu";
import { CgSpinner } from "react-icons/cg";
import { Form, Pagination, Table } from "react-bootstrap";
import { AnimatePresence, motion } from "framer-motion";
import {
    dropdownTransition,
    dropdownVariants,
    fadeTransition,
    fadeVariants,
    listContentTransition,
    listContentVariants,
    pageTitleTransition,
    pageTitleVariants,
    slideFromLeftTransition,
    slideFromLeftVariants,
    slideFromRightOnMountTransition,
    slideFromRightTransition,
    slideFromRightVariants,
    viewportOnce,
} from "../../../../utils/pageMotionVariants";

export default function Users() {

    const [users, setUsers] = useState<User[]>([]);
    const [error, setError] = useState<ApiErrorResponse | null>(null);
    const [loading, setLoading] = useState(true);
    const [search, setSearch] = useState<string>("");
    const [selectedUsers, setSelectedUsers] = useState<string>("all");
    const [showFilterDropdown, setShowFilterDropdown] = useState(false);
    const [currentPage, setCurrentPage] = useState(1);
    const [lastPage, setLastPage] = useState(1);
    const [listTotal, setListTotal] = useState(0);
    const [loadingUsers, setLoadingUsers] = useState(false);
    const debouncedSearch = useDebounce(search, 500);
    const listContentKey = `${currentPage}-${debouncedSearch}-${selectedUsers}`;

    useEffect(() => {
        index(debouncedSearch);
    }, [currentPage, selectedUsers, debouncedSearch]);

    async function index(debouncedSearch: string) {
        setLoadingUsers(true);
        try {
            const response = await fetch(`${API_URL}/api/users?page=${currentPage}&filter=${selectedUsers}&search=${encodeURIComponent(debouncedSearch)}`, {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                    Authorization: `Bearer ${localStorage.getItem("token")}`
                },
            });

            const data = await response.json();

            if (response.ok) {
                setUsers(Array.isArray(data.data.data) ? data.data.data : []);
                setLastPage(data.data.last_page);
                setListTotal(data.data.total);
                setLoadingUsers(false);
                setError(null);
            } else {
                setUsers([]);
                setLastPage(1);
                setListTotal(0);
                setLoadingUsers(false);
                setError(data as ApiErrorResponse);
            }
        } catch (error) {
            console.error(error);
        } finally {
            setLoading(false);
            setLoadingUsers(false);
        }
    }

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

    if (error) {
        return (
            <div className="text-center mt-5">
                <p>{(error as ApiErrorResponse).message}</p>
            </div>
        )
    }

    return (
        <div className={`${styles.container} p-2 p-sm-4 p-lg-0`}>
            <motion.h1 variants={pageTitleVariants} initial="initial" animate="animate" transition={pageTitleTransition} className={styles.title}>Utilizadores</motion.h1>

            <div className="row py-3 g-4 justify-content-between">
                <motion.div variants={slideFromLeftVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={slideFromLeftTransition} className="col-12 col-sm-7 col-md-8 col-lg-6 d-flex gap-2 text-start px-2">
                    <Form.Control type="text" placeholder="Pesquise por nome ou email..." 
                        value={search} onChange={(e) => {
                        setSearch(e.target.value);
                    }} />
                </motion.div>

                <motion.div variants={slideFromRightVariants} initial="initial" whileInView="animate" viewport={viewportOnce} transition={slideFromRightTransition} className="col-12 col-sm-5 col-md-4 col-lg-3 d-flex mt-2 mt-sm-4">
                    <div
                        className="btn-group flex-grow-1 position-relative"
                        onMouseEnter={() => setShowFilterDropdown(true)}
                        onMouseLeave={() => setShowFilterDropdown(false)}
                    >
                        <button type="button" className="btn btn-outline-secondary w-100 dropdown-toggle">
                            <LuSettings2 /> {selectedUsers === 'all' ? 'Todos' : selectedUsers === 'admin' ? 'Administradores' : 'Utilizadores'}
                        </button>

                        <AnimatePresence>
                            {showFilterDropdown && (
                                <motion.ul
                                    variants={dropdownVariants}
                                    initial="initial"
                                    animate="animate"
                                    exit="exit"
                                    transition={dropdownTransition}
                                    className="dropdown-menu text-center w-100"
                                    style={{ display: "block", zIndex: 4000, top: "100%", marginTop: "0.25rem" }}
                                >
                                    <li>
                                        <button
                                            type="button"
                                            className={`dropdown-item ${selectedUsers === "all" ? "active" : ""}`}
                                            onClick={() => { setSelectedUsers("all"); setCurrentPage(1); setLoadingUsers(true); setShowFilterDropdown(false); }}
                                        >
                                            Todos
                                        </button>
                                    </li>
                                    <li>
                                        <button
                                            type="button"
                                            className={`dropdown-item ${selectedUsers === "admin" ? "active" : ""}`}
                                            onClick={() => { setSelectedUsers("admin"); setCurrentPage(1); setLoadingUsers(true); setShowFilterDropdown(false); }}
                                        >
                                            Administradores
                                        </button>
                                    </li>
                                    <li>
                                        <button
                                            type="button"
                                            className={`dropdown-item ${selectedUsers === "user" ? "active" : ""}`}
                                            onClick={() => { setSelectedUsers("user"); setCurrentPage(1); setLoadingUsers(true); setShowFilterDropdown(false); }}
                                        >
                                            Utilizadores
                                        </button>
                                    </li>
                                </motion.ul>
                            )}
                        </AnimatePresence>
                    </div>
                </motion.div>

                <motion.div variants={slideFromRightVariants} initial="initial" animate="animate" transition={slideFromRightOnMountTransition} className="col-12 col-sm col-md-12 col-lg-3 text-end align-content-center mt-4 mt-lg-4">
                    <Link to="/admin/create-user" className={`${styles.createButton} text-decoration-none`}><LuPlus className="mb-1" /> Novo Utilizador</Link>
                </motion.div>
            </div>

            <div className="mt-3">
                <AnimatePresence mode="wait">
                    {loadingUsers ? (
                        <motion.div key="loading" variants={fadeVariants} initial="initial" animate="animate" exit="exit" transition={fadeTransition} className="text-center mt-5">
                            <CgSpinner className={`${styles.animateSpin} text-2xl fs-3`} />
                        </motion.div>
                    ) : (
                        <motion.div
                            key={listContentKey}
                            variants={listContentVariants}
                            initial="initial"
                            animate="animate"
                            exit="exit"
                            transition={listContentTransition}
                        >
            {users.length > 0 ? (
                <div>
                    <div className={`${styles.table} mt-3 mb-2`}>
                        <Table responsive className="mb-0">
                            <thead className="table-light">
                                <tr>
                                    <th className="py-3">ID</th>
                                    <th className="py-3">Name</th>
                                    <th className="py-3">Email</th>
                                    <th className="py-3">Cargo</th>
                                    <th className="py-3">...</th>
                                </tr>
                            </thead>
                            <tbody>
                                {users.map((user) => (
                                    <tr key={user.id}>
                                        <td className="py-3">{user.id}</td>
                                        <td className="py-3">{user.name}</td>
                                        <td className="py-3">{user.email}</td>
                                        <td className="py-3 px-3" >
                                            <span className={`p-2 rounded-3 ${user.role_id === 1 ? 'text-primary bg-primary-subtle' : 'text-secondary bg-secondary-subtle'}`}>
                                                {user.role_id === 1 ? "Administrador" : "Utilizador"}
                                            </span>
                                        </td>
                                        <td className="py-3">
                                            <div className="d-flex gap-2 justify-content-evenly">
                                                <Link to={`/admin/user/${user.id}`}><LuPencil className="text-red-500" /></Link>
                                            </div>
                                        </td>
                                    </tr>
                                ))}
                            </tbody>
                        </Table>
                    </div>

                    <div className="d-flex justify-content-center align-items-center gap-3 py-3">
                        <Pagination>
                            <Pagination.Prev
                                disabled={currentPage <= 1}
                                onClick={() => { setCurrentPage((p) => p - 1); setLoadingUsers(true); }}
                            />

                            {currentPage > 3 && <Pagination.Item onClick={() => { setCurrentPage(1); setLoadingUsers(true); }}>1</Pagination.Item>}
                            {currentPage > 4 && <Pagination.Ellipsis disabled />}

                            {Array.from({ length: 5 }, (_, i) => currentPage - 2 + i)
                                .filter((p) => p >= 1 && p <= lastPage)
                                .map((p) => (
                                    <Pagination.Item key={p} active={p === currentPage} onClick={() => { setCurrentPage(p); setLoadingUsers(true); }}>
                                        {p}
                                    </Pagination.Item>
                                ))}

                            {currentPage < lastPage - 3 && <Pagination.Ellipsis disabled />}
                            {currentPage < lastPage - 2 && (
                                <Pagination.Item onClick={() => { setCurrentPage(lastPage); setLoadingUsers(true); }}>{lastPage}</Pagination.Item>
                            )}

                            <Pagination.Next
                                disabled={currentPage >= lastPage}
                                onClick={() => { setCurrentPage((p) => p + 1); setLoadingUsers(true); }}
                            />
                        </Pagination>
                    </div>
                </div>
            ) : users.length === 0 && !error && (
                <div className="text-center mt-5 d-flex flex-column align-items-center justify-content-center">
                    {selectedUsers === "all" && listTotal === 0 && search === "" ? (
                        <>
                            <span className="text-muted">Sem registo de utilizadores</span>
                        </>
                    ) : (
                        <span className="text-muted">Nenhum utilizador encontrado com o filtro selecionado</span>
                    )}
                </div>
            )}
                        </motion.div>
                    )}
                </AnimatePresence>
            </div>
        </div>
    )
}