"use client";

import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";

import styles from "@/components/administrator/TagData/tagdata.module.css";

import Pagination from "@/components/ui/Pagination/pagination";
import Loader from "@/components/web/Loader/loader";
import Table from "@/components/administrator/Table/table";
import NewTag from "../NewTag/new.tag";

import { useSearch } from "@/hooks/useSearch";
import { useTerm } from "@/hooks/useTerm";

import { FiSearch } from "react-icons/fi";
import { IoCloseOutline } from "react-icons/io5";
import { useRouter, useSearchParams } from "next/navigation";
import { termServices } from "@/app/services/api/term.services";

/**
 * @type {React.FC <{
 *     initialData: any[];
 *     limit: number;
 *     sort: object;
 * }>}
 * @returns
 */
const TagsData = (props) => {
  const searchref = useRef(null);
  const router = useRouter();

  const searchParams = useSearchParams();

  const [tags, setTags] = useState(props.initialData.data);
  const [selected, setSelected] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  const tagsData = useMemo(() => tags, [tags]);

  const {
    isLoading: loadSearch,
    isSearch,
    handleInput,
    handleSubmit,
    setInitialData,
    setSearchFn,
    setSetDataFn,
    setFallbackFn,
    cancel,
  } = useSearch();
  const { deletemultipleTag } = useTerm();

  const getSortedData = useCallback(async ({ page, limit }, sort) => {
    const data = await termServices.getTags({ page, limit }, sort);
    setTags(data.data);
  }, []);

  const setData = useCallback((data) => {
    setTags(data);
  }, []);

  const fallback = useCallback(async (keyword, limit = 100) => {
    const result = await termServices.getTags(
      { page: 1, limit },
      { name: -1 },
      keyword
    );

    return result.data;
  }, []);

  useEffect(() => {
    setIsLoading(loadSearch);
  }, [loadSearch]);

  return (
    <div className={styles.post_container}>
      <div className={styles.post_header}>
        <div className={styles.header_wrapper}>
          <h1>Tags Management</h1>
          <div className={styles.post_action}>
            {selected.length > 0 && (
              <div className={styles.post_status}>
                <p>
                  Selected:{" "}
                  <span>
                    {selected.length} item{selected.length > 1 && "s"}
                  </span>{" "}
                </p>
                <p>
                  <span
                    className={styles.action}
                    onClick={async () => {
                      deletemultipleTag(
                        selected.map((tag) => tag._id),
                        (result) => {
                          setSelected([]);
                          setTags((prev) =>
                            prev.filter(
                              (tag) =>
                                !result.map((tag) => tag._id).includes(tag._id)
                            )
                          );
                        }
                      );
                    }}>
                    Delete item{selected.length > 1 && "s"}
                  </span>{" "}
                </p>
              </div>
            )}
            <NewTag
              className={styles.post_button}
              fontSize={13}
              getTag={(result) => {
                setTags((prev) => [result, ...prev]);
              }}>
              Add Tag
            </NewTag>
          </div>
        </div>
        <div className={styles.header_wrapper}>
          <form
            className={styles.search_container}
            onSubmit={handleSubmit}>
            <FiSearch />
            <input
              type="text"
              ref={searchref}
              placeholder="Search Tags"
              defaultValue={props.initialData?.keyword || ""}
              onInput={handleInput}
              onFocus={() => {
                if (!isSearch) setInitialData(tags);

                setSearchFn(fallback);
                setFallbackFn(async () => {
                  setIsLoading(true);
                  const data = await fallback(null, props?.limit);
                  setIsLoading(false);
                  setData(data);
                });
                setSetDataFn(setData);
              }}
            />
            {isSearch && (
              <IoCloseOutline
                onClick={() => {
                  searchref.current.value = "";
                  cancel();
                }}
                style={{ cursor: "pointer" }}
              />
            )}
          </form>
        </div>
      </div>
      {isLoading ? (
        <div className={styles.loader_container}>
          <div className={styles.loader}>
            <Loader
              color="#000"
              width={30}
            />
            <p>Getting data</p>
          </div>
        </div>
      ) : (
        <Table
          data={tagsData}
          selected={selected}
          limit={props.limit}
          role={{
            name: "Name",
            slug: "Slug",
            description: "Description",
          }}
          sortRole={{
            canSorting: true,
            sortingFn: getSortedData,
          }}
          onClick={(data) => {
            router.push(`/dashboard/tags/${data._id}`);
          }}
          onSelected={(data) => {
            setSelected(data);
          }}
        />
      )}
      {!isSearch && (
        <div className={styles.pagination}>
          <Pagination
            totalPage={props.initialData.totalPage}
            currentPage={(() => {
              const page = parseInt(
                Object.fromEntries(searchParams.entries())?.page
              );
              return page || props.initialData.page;
            })()}
            getData={termServices.getTags}
            getIsLoading={(status) => setIsLoading(status)}
            setData={(data) => setTags(data.data)}
            limit={props.limit}
            sort={props.sort}
          />
        </div>
      )}
    </div>
  );
};

export default TagsData;
