"use client";

import { SortDirection } from "@/components/ui/tableSortContext";
import { apiDefaultParams } from "@/constants/Api_Params";
import { AdminStatus } from "@/constants/enums";
import {
  useChangeAdminStatus,
  useDeleteAdmin,
  useGetAdminListQuery,
  useResetAdminPassword,
} from "@/hooks/queries";
import { IUser, TChangeAdminStatusCredentials } from "@/lib/api";
import { useHybridPagination } from "@/hooks/useHybridPagination";
import {
  buildQueryString,
  deleteEmptyKeys,
  getPaginatedRowNumber,
} from "@/utils/shared";
import gsap from "gsap";
import { useIsMutating } from "@tanstack/react-query";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import {
  useCallback,
  useEffect,
  useLayoutEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useForm } from "react-hook-form";

export const useAdminsPresenter = () => {
  const [isChangeStatusModalOpen, setIsChangeStatusModalOpen] = useState(false);
  const [currentUser, setCurrentUser] = useState<IUser | null>(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isResetPasswordModalOpen, setIsResetPasswordModalOpen] =
    useState(false);
  const [generatedPassword, setGeneratedPassword] = useState<string | null>(
    null,
  );
  const [status, setStatus] = useState<string>(
    currentUser?.status ?? AdminStatus.ACTIVE,
  );
  const isMutating = useIsMutating();
  const router = useRouter();
  const searchParams = useSearchParams();
  const {
    register: filterRegister,
    handleSubmit: handleFilterSubmit,
    reset: filterFormReset,
    watch,
    setValue: setFilterValue,
  } = useForm();

  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm<TChangeAdminStatusCredentials>({
    mode: "onChange",
    defaultValues: {
      status: currentUser?.status ?? "",
    },
  });
  const [params, setParams] = useState<Record<string, any>>({});
  const pathName = usePathname();

  const tableSectionRef = useRef<HTMLDivElement>(null);
  const skeletonTbodyRef = useRef<HTMLTableSectionElement>(null);
  const dataTbodyRef = useRef<HTMLTableSectionElement>(null);

  useEffect(() => {
    const newParams: Record<string, unknown> = {
      ...apiDefaultParams,
      offset: 0,
      limit: 10,
    };
    for (const [key, value] of searchParams.entries()) {
      newParams[key] = value;
    }
    setParams(newParams);
    filterFormReset(newParams);
  }, [searchParams, filterFormReset]);

  const { data, isPending, isError, error } = useGetAdminListQuery(params);

  const { pagination, handlePaginationChange, buildFirstPageParams } =
    useHybridPagination({
      meta: data?.meta,
      params,
      setParams,
      isError,
      error,
    });

  const shouldShowPagination =
    !isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10;

  const usersList = data?.data?.users ?? [];
  const metadata = data?.meta;

  const getRowNumber = useCallback(
    (index: number) =>
      getPaginatedRowNumber({
        index,
        page: data?.meta?.page,
        limit: data?.meta?.limit,
      }),
    [data?.meta?.limit, data?.meta?.page],
  );

  const navigateToEditAdmin = useCallback(
    (userId: string) => {
      router.push(`/admins/edit/${userId}`);
    },
    [router],
  );

  const openDeleteModalForUser = useCallback((user: IUser) => {
    setCurrentUser(user);
    setIsModalOpen(true);
  }, []);

  const openChangeStatusModalForUser = useCallback((user: IUser) => {
    setCurrentUser(user);
    setIsChangeStatusModalOpen(true);
  }, []);

  const { mutate: resetAdminPassword, isPending: isResettingPassword } =
    useResetAdminPassword({
      successCallback: (password) => setGeneratedPassword(password),
    });

  const openResetPasswordModalForUser = useCallback(
    (user: IUser) => {
      setCurrentUser(user);
      setGeneratedPassword(null);
      setIsResetPasswordModalOpen(true);
      resetAdminPassword(user.id);
    },
    [resetAdminPassword],
  );

  const closeResetPasswordModal = useCallback(() => {
    setIsResetPasswordModalOpen(false);
    setGeneratedPassword(null);
  }, []);

  useLayoutEffect(() => {
    const reduced =
      typeof window !== "undefined" &&
      window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    const ctx = gsap.context(() => {
      if (reduced) return;

      if (isPending) {
        const tbody = skeletonTbodyRef.current;
        if (!tbody) return;
        const rows = tbody.querySelectorAll("tr");
        gsap.fromTo(
          rows,
          { opacity: 0.35, y: 14 },
          {
            opacity: 1,
            y: 0,
            duration: 0.42,
            stagger: 0.032,
            ease: "power2.out",
          },
        );
        return;
      }

      const tbody = dataTbodyRef.current;
      if (!tbody) return;
      const rows = tbody.querySelectorAll("tr");
      if (!rows.length) return;
      gsap.fromTo(
        rows,
        { opacity: 0, y: 18 },
        {
          opacity: 1,
          y: 0,
          duration: 0.46,
          stagger: 0.05,
          ease: "power3.out",
          clearProps: "opacity,transform",
        },
      );
    }, tableSectionRef);

    return () => ctx.revert();
  }, [isPending, data]);

  const { mutate: deleteAdmin } = useDeleteAdmin(() => {
    setIsModalOpen(false);
  });

  const onConfirmDelete = () => {
    if (currentUser) {
      deleteAdmin(currentUser.id);
    }
  };

  const { mutate: changeStatus } = useChangeAdminStatus({
    id: currentUser?.id ?? "",
    successCallback: () => {
      setIsChangeStatusModalOpen(false);
    },
  });

  const search = (formData: any) => {
    const newParams = buildFirstPageParams({ ...params, ...formData });
    const cleanedParams = deleteEmptyKeys(newParams);
    const queryString = new URLSearchParams(cleanedParams).toString();
    router.push(`${pathName}?${queryString}`);
  };

  const clearAllFilters = useCallback(() => {
    filterFormReset({
      ...apiDefaultParams,
      offset: 0,
      limit: 10,
      search: "",
      status: "",
    });
    router.push(pathName);
  }, [filterFormReset, pathName, router]);

  const columns = [
    "row",
    "full name",
    "email",
    "username",
    "status",
    "actions",
  ];

  /** Column label → BSON `sort_by` field. */
  const columnSortKeys: Record<string, string> = {
    "full name": "full_name",
    email: "email",
    username: "username",
    status: "status",
  };

  /** First-click direction per column. */
  const columnDefaultOrder: Record<string, SortDirection> = {
    "full name": "asc",
    email: "asc",
    username: "asc",
  };

  const sortBy = (params.sort_by as string) ?? "created_at";
  const sortOrder = (params.sort_order as SortDirection) ?? "desc";

  const handleSortChange = useCallback(
    (key: string, order: SortDirection) => {
      const newParams = buildFirstPageParams({
        ...params,
        sort_by: key,
        sort_order: order,
      });
      const cleanedParams = deleteEmptyKeys(newParams);
      const queryString = buildQueryString(cleanedParams);
      router.push(`${pathName}?${queryString}`);
    },
    [buildFirstPageParams, params, pathName, router],
  );

  return {
    allUsers: usersList,
    usersList,
    setFilterValue,
    metadata,
    columns,
    columnSortKeys,
    columnDefaultOrder,
    sortBy,
    sortOrder,
    handleSortChange,
    isPending,
    onConfirmDelete,
    isModalOpen,
    setIsModalOpen,
    isMutating,
    setCurrentUser,
    pathName,
    status,
    setStatus,
    changeStatus,
    isChangeStatusModalOpen,
    currentUser,
    setIsChangeStatusModalOpen,
    register,
    errors,
    handleSubmit,
    setParams,
    filterRegister,
    handleFilterSubmit,
    search,
    watch,
    shouldShowPagination,
    clearAllFilters,
    tableSectionRef,
    skeletonTbodyRef,
    dataTbodyRef,
    getRowNumber,
    pagination,
    handlePaginationChange,
    navigateToEditAdmin,
    openDeleteModalForUser,
    openChangeStatusModalForUser,
    isResetPasswordModalOpen,
    closeResetPasswordModal,
    openResetPasswordModalForUser,
    generatedPassword,
    isResettingPassword,
  };
};
