import { createRef, useEffect, useRef } from "react";
import { useState } from "react";
import { FiLink } from "react-icons/fi";
import useFilter from "../../hooks/useFilter.hook.jsx";
import styles from "../../styles/pdf_gen/selectExo.module.scss";
import { isBrowser, isEmpty, parseClassName } from "../../utils/utils.js";
import TagSelect from "../exos/TagSelect.jsx";
import Modal from "../Modal.jsx";
import Tag from "../Tag.jsx";
import ParamItem from "./ParamItem.jsx";
import TagContainer from "./tagContainer.jsx";
import { AiOutlineClose } from "react-icons/ai";
import { useInfiniteQuery, useQuery } from "react-query";
import {
  getExos,
  getPublicExos,
  getTags,
  getUserExos,
} from "../../requests/requests.exos.js";
import { useInView } from "react-intersection-observer";
import { useSessionContext } from "../../context/session.context.js";

export default function SelectExo({
  exos,
  setExos,
  emptyError,
  onlyNumber = false,
}) {
  const { ref, inView } = useInView();
  const [active, setActive] = useState(false);

  const { data: tagsData } = useQuery(
    ["tags"],
    async () => {
      return await getTags();
    },
    { enabled: active, staleTime: 60 * 1000 }
  );
  const [selectedOption, setSelectedOption] = useState([]);
  const [selectFilter, setSelectFilter] = useState(
    isBrowser && localStorage.getItem("token") != null ? "user" : "all"
  );
  const [search, setSearch] = useState("");
 

  const {
    isLoading,
    isError,
    data,
    fetchNextPage,
    hasNextPage,
    isFetching,
    isFetchingNextPage,
  } = useInfiniteQuery(
    ["userExo-data", { search, tags: selectedOption.map((t) => t.value) }],
    ({ pageParam = 0 }) => {
      return getUserExos("pdf", pageParam == 0 ? 1 : pageParam, {
        search,
        tags: selectedOption.map((t) => t.value),
      }).then((res) => {
        return {
          ...res,
          results: [
            ...res.results.map((r) => {
              return { ...r, numberInExo: 10, numberOfExo: 1 };
            }),
          ],
        };
      });
    },
    {
      enabled: (active && selectFilter == "user") /* || exos.length != 0 */,
      staleTime: 60 * 1000,
      refetchOnWindowFocus: false,
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) =>
        firstPage.links.previous ? firstPage.page_number - 1 : undefined,
      getNextPageParam: (lastPage) =>
        lastPage.links.next ? lastPage.page_number + 1 : undefined,
    }
  );
  const {
    isLoading: publicLoading,
    isError: publicError,
    data: publicData,
    fetchNextPage: publicFetchNextPage,
    hasNextPage: publicHasNextPage,
    isFetching: publicFetching,
    isFetchingNextPage: publicIsFetchingNextPage,
  } = useInfiniteQuery(
    ["publicExo-data", { search, tags: selectedOption.map((t) => t.value) }],
    ({ pageParam = 0 }) => {
      return getPublicExos("pdf", pageParam == 0 ? 1 : pageParam, {
        search,
        tags: selectedOption.map((t) => t.value),
      }).then((res) => {
        return {
          ...res,
          results: [
            ...res.results.map((r) => {
              return { ...r, numberInExo: 10, numberOfExo: 1 };
            }),
          ],
        };
      });
    },
    {
      enabled: (active && selectFilter == "all") /* || exos.length != 0 */,
      staleTime: 60 * 1000,
      refetchOnWindowFocus: false,
      keepPreviousData: true,
      getPreviousPageParam: (firstPage) =>
        firstPage.links.previous ? firstPage.page_number - 1 : undefined,
      getNextPageParam: (lastPage) =>
        lastPage.links.next ? lastPage.page_number + 1 : undefined,
    }
  );

  useEffect(() => {
    if (inView) {
      selectFilter == "user" ? fetchNextPage() : publicFetchNextPage();
    }
  }, [inView]);

  const {authData} = useSessionContext()

  return (
    <>
      <div className={styles["exo-select"]}>
        <div className={styles["head"]}>
          <p>Ajouter exercices</p>
          <p className={styles.add} onClick={() => setActive(true)}>
            +
          </p>
        </div>
        <div className={styles["exos-selected"]}>
          {exos.length === 0 && (
            <>
              <p
                className={parseClassName([
                  styles["no-select"],
                  emptyError ? styles["error-empty"] : undefined,
                ])}
              >
                Aucun exercice selectionné
              </p>
              {emptyError == true && (
                <p className={parseClassName(["error-msg", styles.error])}>
                  Veuillez selectionner un exercice au minimum
                </p>
              )}
            </>
          )}

          {exos.map((s, i) => {
            return (
              <ParamItem
                exo={{
                  name: s.name,
                  ...exos.filter((ex) => ex.id_code == s.id_code)[0],
                }}
                unSelect={() => {
                  setExos((o) => [
                    ...o.filter((ex) => {
                      return ex.id_code != s.id_code;
                    }),
                  ]);
                }}
                setExo={(nbIn, nbOf) => {
                  setExos((o) => [
                    ...o.map((ex) => {
                      if (ex.id_code == s.id_code) {
                        return {
                          ...ex,
                          numberInExo: nbIn,
                          numberOfExo: nbOf,
                        };
                      }
                      return ex;
                    }),
                  ]);
                }}
                key={i}
                onlyNumber={onlyNumber}
              />
            );
          })}
          {/* {[
            ...(data || { pages: [] }).pages,
            ...(publicData || { pages: [] }).pages,
          ]
            .map((p) => p.results)
            .flat()
            .filter((e) => {
              return exos.map((ex) => ex.id_code).includes(e.id_code);
            })
            .sort((a, b) => {
              return (
                exos.map((ex) => ex.id_code).indexOf(a.id_code) -
                exos.map((ex) => ex.id_code).indexOf(b.id_code)
              );
            })
            .map((s, i) => {
              return (
                <ParamItem
                  exo={{
                    name: s.name,
                    ...exos.filter((ex) => ex.id_code == s.id_code)[0],
                  }}
                  unSelect={() => {
                    setExos((o) => [
                      ...o.filter((ex) => {
                        return ex.id_code != s.id_code;
                      }),
                    ]);
                  }}
                  setExo={(nbIn, nbOf) => {
                    setExos((o) => [
                      ...o.map((ex) => {
                        if (ex.id_code == s.id_code) {
                          return {
                            ...ex,
                            numberInExo: nbIn,
                            numberOfExo: nbOf,
                          };
                        }
                        return ex;
                      }),
                    ]);
                  }}
                  key={i}
                  onlyNumber={onlyNumber}
                />
              );
            })} */}
        </div>
      </div>
      <Modal active={active} onClose={() => setActive(false)}>
        <div className={styles["modal-list-container"]}>
          <div className={styles["search-container"]}>
            <input
              type="text"
              className="exo-input"
              placeholder="Rechercher..."
              value={search}
              onChange={(e) => {
                setSearch(e.target.value);
              }}
            />

            <div style={{ display: "flex" }}>
              {tagsData && !isEmpty(authData) && (
                <TagSelect
                  tags={tagsData}
                  onChange={setSelectedOption}
                  select={selectedOption}
                />
              )}
              {!isEmpty(authData) && (
                <select
                  className={styles.select}
                  value={selectFilter}
                  onChange={(e) => {
                    setSelectFilter(e.target.value);
                  }}
                >
                  <option value="all">Tous</option>
                  <option value="user">User</option>
                </select>
              )}
            </div>
          </div>
          <div>
            {selectFilter == "user" &&
              data &&
              data.pages.map((p) => p.results).flat().length == 0 && (
                <p className={styles["no-select"]}>Aucun résultat</p>
              )}
            {selectFilter == "all" &&
              publicData &&
              publicData.pages.map((p) => p.results).flat().length == 0 && (
                <p className={styles["no-select"]}>Aucun résultat</p>
              )}

            {selectFilter == "user" &&
              data &&
              data.pages.map((page) => {
                return page.results.map((d, i) => {
                  return (
                    <div
                      key={i}
                      onClick={() => {
                        if (!exos.map((ex) => ex.id_code).includes(d.id_code)) {
                          setExos((o) => [
                            ...o,
                            {
                              id_code: d.id_code,
                              numberInExo: d.numberInExo,
                              numberOfExo: d.numberOfExo,
                              name: d.name,
                            },
                          ]);
                        } else {
                          setExos((o) => [
                            ...o.filter((ex) => {
                              return ex.id_code != d.id_code;
                            }),
                          ]);
                        }
                      }}
                      className={parseClassName([
                        exos.map((ex) => ex.id_code).includes(d.id_code)
                          ? styles["selected"]
                          : undefined,
                        styles["item-in-modal"],
                        "pointer",
                      ])}
                    >
                      <div className={styles["modal-name"]}>{d.name}</div>

                      {d.tags.length !== 0 && <TagContainer tags={d.tags} />}
                    </div>
                  );
                });
              })}

            {selectFilter == "all" &&
              publicData &&
              publicData.pages.map((page) => {
                return page.results.map((d, i) => {
                  return (
                    <div
                      key={i}
                      onClick={() => {
                        if (!exos.map((ex) => ex.id_code).includes(d.id_code)) {
                          setExos((o) => [
                            ...o,
                            {
                              id_code: d.id_code,
                              numberInExo: d.numberInExo,
                              numberOfExo: d.numberOfExo,
                              name: d.name,
                            },
                          ]);
                        } else {
                          setExos((o) => [
                            ...o.filter((ex) => {
                              return ex.id_code != d.id_code;
                            }),
                          ]);
                        }
                      }}
                      className={parseClassName([
                        exos.map((ex) => ex.id_code).includes(d.id_code)
                          ? styles["selected"]
                          : undefined,
                        styles["item-in-modal"],
                        "pointer",
                      ])}
                    >
                      <div className={styles["modal-name"]}>{d.name}</div>

                      {d.tags.length !== 0 && <TagContainer tags={d.tags} />}
                    </div>
                  );
                });
              })}
            <span ref={ref}></span>
            {isFetchingNextPage ||
              (isFetching && (
                <div className={styles["loader-container"]}>
                  <span className="loader"></span>
                </div>
              ))}
            {publicIsFetchingNextPage ||
              (publicFetching && (
                <div className={styles["loader-container"]}>
                  <span className="loader"></span>
                </div>
              ))}
          </div>
        </div>
        <div className={styles["icon-container"]}>
          <AiOutlineClose
            className={styles["icon"]}
            onClick={() => {
              setActive(false);
            }}
          />
        </div>
      </Modal>
    </>
  );
}
