import axios from "axios";
import Layout from "../../components/Layout.js";
import { useState, useEffect, useCallback, useRef } from "react";
import { Card } from "../../components/exos/Card.jsx";
import {
  getExos,
  getPublicExos,
  getTags,
  getUserExos,
} from "../../requests/requests.exos.js";
import { useQuery, useQueryClient } from "react-query";
import styles from "../../styles/exos/ExercicesPage.module.scss";
import Modal from "../../components/Modal.jsx";
import ModalCard from "../../components/exos/ModalCard.jsx";
import { useRouter } from "next/router";
import ExoCreateForm from "../../components/exos/ExoCreateForm.jsx";
import TagSelect from "../../components/exos/TagSelect.jsx";
import { FiLink } from "react-icons/fi";
import { isBrowser, parseClassName } from "../../utils/utils.js";
import useFilter from "../../hooks/useFilter.hook.jsx";
import { Pagination } from "../../components/exos/Pagination.jsx";
import { useSessionContext } from "../../context/session.context.js";
import { isEmpty } from "../../utils/utils.js";
import { notificationService } from "../../services/notification.service.js";

export default function ExercicesPage() {
  const { authData } = useSessionContext();

  const router = useRouter();
  const { exo } = router.query;
  const [page, setPage] = useState(1); //correspond à l'index

  const [selectFilter, setSelectFilter] = useState(null);
  const queryClient = useQueryClient();

  const [search, setSearch] = useState("");
  const [tmpSearch, setTmpSearch] = useState("");

  useEffect(() => {
    const timeOutId = setTimeout(() => setSearch(tmpSearch), 500);
    return () => {
      clearInterval(timeOutId);
    };
  }, [tmpSearch]);

  const [selectedOption, setSelectedOption] = useState([]);

  const {
    isLoading,
    isError,
    data: publicData,
    isFetching,
  } = useQuery(
    [
      "public-data",
      parseInt(page),
      { search, tags: selectedOption.map((t) => t.value) },
    ],
    async () =>
      await getPublicExos("all", page, {
        search,
        tags: selectedOption.map((t) => t.value),
      }),

    {
      refetchOnWindowFocus: false,
      enabled: selectFilter == "all",
      staleTime: 60000,
      keepPreviousData: true,
    }
  );

  const {
    isLoading: userLoading,
    isError: userError,
    data: userExosData,
    isFetching: userFetching,
  } = useQuery(
    [
      "user-data",
      parseInt(page),
      { search, tags: selectedOption.map((t) => t.value) },
    ],
    async () =>
      await getUserExos("all", page, {
        search,
        tags: selectedOption.map((t) => t.value),
      }),
    {
      refetchOnWindowFocus: false,
      enabled: selectFilter == "user" && !isEmpty(authData),
      staleTime: 60000,
      keepPreviousData: true,
    }
  );
  const { data: tagsData } = useQuery(
    ["tags"],
    async () => {
      return await getTags();
    },
    {
      enabled: !isEmpty(authData),
      initialData: [],
      staleTime: 2 * 60 * 1000,
      initialDataUpdatedAt: 10 * 1000 * 60,
    }
  );

  const [activeData, setActiveData] = useState({
    active: false,
    data: null,
  });

  const [create, setCreate] = useState(false);

  const isLoad = useRef(false);

  useEffect(() => {
    console.log(
      "AUTH DATA",
      authData,
      isLoad,
      isLoad.current || authData !== undefined
    );
    if (exo !== undefined && (/* isLoad.current ||  */authData !== undefined)) {
      if (exo[0] == "public") {
        setSelectFilter("all");
      } else if (exo[0] == "user") {
        if (!isEmpty(authData)) {
          setSelectFilter("user");
        } else {
          router.push({ pathname: "/exercices/public", query: { page: 1 } });
        }
      } else {
        if (selectFilter === null) {
          setSelectFilter(!isEmpty(authData) ? "user" : "public");
        }
        getExos(exo[0])
          .then((res) => {
            setActiveData({ active: true, data: { ...res } });
          })
          .catch(() => {
            router.push({
              pathname:
                "/exercices/" + (!isEmpty(authData) ? "user" : "public"),
              query: { page: 1 },
            });
            notificationService.error("Erreur", "Exercice introuvable", {
              keepAfterRouteChange: true,
            });
          });
      }
    } else if (exo === undefined && (/* isLoad.current || */ authData !== undefined)) {
      if (selectFilter === null) {
        router.push({
          pathname: "/exercices/" + (!isEmpty(authData) ? "user" : "public"),
          query: { page: 1 },
        });
      }
    } 

    if (!isLoad.current) {
      isLoad.current = true;
    }
    return () => {
      setActiveData({ active: false, data: null });
    };
  }, [router.asPath, authData, isLoad, selectFilter]);

  useEffect(() => {
    if (publicData && router.query.page && selectFilter == "all") {
      if (publicData.pages && parseInt(router.query.page) <= publicData.pages) {
        setPage(parseInt(router.query.page));
      } else if (
        publicData.pages &&
        parseInt(router.query.page) > publicData.pages
      ) {
        var exo = router.query.exo || [];
        router.push(
          {
            pathname: "/exercices/" + exo.join("/"),
            query: { page: publicData.pages },
          },
          undefined,
          { shallow: true }
        );
      } else if (parseInt(router.query.page) == 0) {
        var exo = router.query.exo || [];
        router.push(
          {
            pathname: "/exercices/" + exo.join("/"),
            query: { page: 1 },
          },
          undefined,
          { shallow: true }
        );
      }
    }
    if (userExosData && router.query.page && selectFilter == "user") {
      if (
        userExosData.pages &&
        parseInt(router.query.page) <= userExosData.pages
      ) {
        setPage(parseInt(router.query.page));
      } else if (
        userExosData.pages &&
        parseInt(router.query.page) > userExosData.pages
      ) {
        var exo = router.query.exo || [];
        router.push(
          {
            pathname: "/exercices/" + exo.join("/"),
            query: { page: userExosData.pages },
          },
          undefined,
          { shallow: true }
        );
      }
    }
  }, [router.asPath, publicData, userExosData, selectFilter]);

  const [deleted, setDeleted] = useState([]);

  const onClose = () => {
    if (activeData.active == true) {
      setActiveData({ active: false, data: { ...activeData.data } });
      queryClient.invalidateQueries(
        selectFilter == "all" ? "public-data" : "user-data"
      );
      router.push(
        {
          pathname: "/exercices/" + (selectFilter == "all" ? "public" : "user"),
          query: { page: page },
        },
        undefined,
        { shallow: true }
      );
      setTimeout(() => {
        setActiveData({ active: false, data: null });
      }, 300); // le temps de la transition
    } else if (create == true) {
      setCreate(false);
    }
  };
  return (
    <Layout page="Tous les exercices">
      <div className={parseClassName([styles["all_exos--full_container"]])}>
        {isLoading ||
          isFetching ||
          userLoading ||
          (userFetching && (
            <p
              style={{
                textAlign: "center",
                position: "absolute",
                width: "100%",
              }}
            >
              <span className="loader"></span>
            </p>
          ))}

        <div className={styles["all_exos--head"]}>
          <div className={styles["new-container"]}>
            {!isEmpty(authData) && (
              <button
                onClick={() => {
                  setCreate(true);
                }}
              >
                Nouveau +
              </button>
            )}
          </div>

          <div className={styles["search-full-container"]}>
            <input
              placeholder="Rechercher..."
              type="text"
              className="exo-input"
              value={tmpSearch}
              onChange={(e) => {
                setTmpSearch(e.target.value);
                setPage(1);
              }}
            />
            <div style={{ display: "flex", width: '100%' }}>
              {!isEmpty(authData) && (
                <TagSelect
                  tags={tagsData ? tagsData: []}
                  onChange={(e) => {
                    setSelectedOption(e);
                    setPage(1);
                  }}
                  select={selectedOption}
                />
              )}
            </div>
            {!isEmpty(authData) && (
              <select
                onChange={(e) => {
                  router.push(
                    {
                      pathname:
                        "/exercices/" +
                        (e.target.value == "user" ? "user" : "public"),
                      query: { page: 1 },
                    },
                    undefined,
                    { shallow: true }
                  );
                  setSelectFilter(e.target.value);

                  setPage(1);
                }}
                value={selectFilter}
                className={styles.select}
              >
                <option value="user">Vos exercices</option>
                <option value="all">Tous les exercices</option>
              </select>
            )}
          </div>
        </div>
        <div className={styles["all_exos--container"]}>
          <div className={styles["all_exos--title"]}>
            {selectFilter == "all" && (
              <h1>
                Tous les <span className="primary">exercices</span>
              </h1>
            )}

            {selectFilter == "user" && (
              <h1>
                Tous vos <span className="primary">exercices</span>
              </h1>
            )}
            {selectFilter == "user" && (
              <p>
                Vous retrouverez ici tous les exercices que vous avez créé ou
                copié depuis les exercices publics
              </p>
            )}
            {selectFilter == "all" && (
              <p>
                Vous retrouverez ici tous les exercices crées par les autres
                utilisateurs
              </p>
            )}
          </div>

          {selectFilter == "all" &&
            publicData &&
            publicData.results
              //.sort((a, b) => a.id - b.id)
              //.slice(page * inPage, (page + 1) * inPage)
              .map((step) => {
                return (
                  <Card
                    queryKey={[
                      "public-data",
                      parseInt(page),
                      {
                        search,
                        tags: selectedOption.map((e) => e.value),
                      },
                    ]}
                    key={step.id}
                    step={step}
                    setActive={setActiveData}
                    deleted={deleted.includes(step.id_code)}
                    tags={tagsData}
                  />
                );
              })}

          {selectFilter == "user" &&
            userExosData &&
            userExosData.results.map((step) => {
              return (
                <Card
                  queryKey={[
                    "user-data",
                    parseInt(page),
                    {
                      search,
                      tags: selectedOption.map((e) => e.value),
                    },
                  ]}
                  key={step.id}
                  step={step}
                  setActive={setActiveData}
                  deleted={deleted.includes(step.id_code)}
                  tags={tagsData}
                  setRegistered={(reg) => {}}
                />
              );
            })}

          {publicData &&
            publicData.results.length == 0 &&
            selectFilter == "all" && <p>Aucun résultat</p>}
          {userExosData &&
            userExosData.results.length == 0 &&
            selectFilter == "user" && <p>Aucun résultat</p>}
        </div>

        {selectFilter == "all" && publicData && publicData.pages != 1 && (
          <Pagination setPage={setPage} page={page} pages={publicData.pages} />
        )}

        {selectFilter == "user" && userExosData && userExosData.pages != 1 && (
          <Pagination
            setPage={setPage}
            page={page}
            pages={userExosData.pages}
          />
        )}
      </div>
      <Modal active={activeData.active || create} onClose={onClose}>
        {activeData.data != null && create == false && (
          <ModalCard
            queryKey={[
              selectFilter == "all" ? "public-data" : "user-data",
              parseInt(page),
              {
                search,
                tags: selectedOption.map((e) => e.value),
              },
            ]}
            step={activeData.data}
            setActive={setActiveData}
            modal={true}
            onClose={onClose}
            onDelete={(id) => {
              if (!deleted.includes(id)) {
                setDeleted([...deleted, id]);
              } else {
                setDeleted([...deleted.filter((d) => d !== id)]);
              }
            }}
            tags={tagsData}
          />
        )}
        {create == true && activeData.data == null && (
          <ExoCreateForm
            cancel={() => {
              setCreate(false);
            }}
            resetFilter={() => {
              setSelectedOption([])
              setSearch('')
            }}
            addExo={(newExo) => {
              setUserExosData((s) => [...s, newExo]);
            }}
          />
        )}
      </Modal>
    </Layout>
  );
}

/* export async function getStaticProps() {
  const exos = await getExos();
  const tags = await getTags();
  return {
    props: {
      exos: exos,
      tags: tags,
    },
    revalidate: 60,
  };
} */

/* export const getStaticPaths = async () => {
  return {
    paths: [], //indicates that no page needs be created at build time
    fallback: "blocking", //indicates the type of fallback
  };
}; */
