import { useQuery } from "@tanstack/react-query";
import api from "../utils/api";
import { User } from "../types/User";
import { Session } from "../types/Session";
import { useState } from "react";
import { App } from "../types/App";
import { useDebounce } from "@uidotdev/usehooks";
import SessionCard from "../components/SessionCard";
import { groupByCreatedAt } from "../utils/groupByCreatedAt";
import { format, isToday } from "date-fns";
import { ru } from "date-fns/locale";
import MultySelect from "../components/MultySelect";
import Button from "../components/Button";
import SearchInput from "../components/SearchInput";
import CloseIcon from "../components/icons/CloseIcon";
import SpinIcon from "../components/icons/SpinIcon";
import pluralize from "../utils/pluralize";

function SessionsPage() {
  const [limit, setLimit] = useState(10);
  const [search, setSearch] = useState<string | null>(null);

  const [managerIds, setManagerIds] = useState<string[]>([]);
  const [appIds, setAppIds] = useState<string[]>([]);
  const [shouldReset, setShouldReset] = useState(false);

  const debouncedSearch = useDebounce(search, 500);

  const { data: me } = useQuery({
    queryKey: ["me"],
    queryFn: () => api.get("auth/me").json<User>(),
  });

  const { data: managers } = useQuery({
    queryKey: ["managers"],
    queryFn: () => api.get("users").json<User[]>(),
    enabled: !!me,
  });

  const { data: apps } = useQuery({
    queryKey: ["apps"],
    queryFn: () => api.get("apps").json<App[]>(),
    enabled: !!me,
  });

  const { data: grouppedSessions, isLoading } = useQuery({
    queryKey: ["sessions", managerIds, appIds, debouncedSearch, limit],
    queryFn: () =>
      api
        .get(
          `sessions?${
            managerIds.length ? `ownerIds=${managerIds.join()}` : ""
          }${appIds.length ? `&appIds=${appIds.join()}` : ""}${
            debouncedSearch ? `&clientSearch=${debouncedSearch}` : ""
          }&limit=${limit}`
        )
        .json<Session[]>(),
    enabled: !!me,
    select: groupByCreatedAt,
  });

  const { data: count } = useQuery({
    queryKey: ["sessions", "count", managerIds, appIds, debouncedSearch],
    queryFn: () =>
      api
        .get(
          `sessions/count?${
            managerIds.length ? `ownerIds=${managerIds.join()}` : ""
          }${appIds.length ? `&appIds=${appIds.join()}` : ""}${
            debouncedSearch ? `&clientSearch=${debouncedSearch}` : ""
          }`
        )
        .json<number>(),
    enabled: !!me,
  });

  function reset() {
    setSearch("");
    setAppIds([]);
    setManagerIds([]);
    setShouldReset(true);
    setTimeout(() => setShouldReset(false), 0);
  }

  return (
    <div className=" flex flex-col gap-[1.667vw]">
      <h1 className="title-l font-medium">Сеансы</h1>
      <div className="p-[1.389vw] rounded-[2.222vw] shadow-[0_4px_40px_0_rgba(15,16,17,0.05),0_2px_2px_0_rgba(15,16,17,0.05)] w-full">
        <div className="space-y-[1.111vw]">
          <div className="flex flex-col gap-[0.556vw]">
            <SearchInput
              placeholder="Поиск по имени клиента"
              value={search || ""}
              onChange={(e) => setSearch(e.target.value)}
              setSearch={setSearch}
            />
            <div className="flex gap-[0.556vw]">
              <MultySelect
                data={
                  managers?.map(({ fullname: name, ...manager }) => ({
                    name,
                    ...manager,
                  })) || []
                }
                isGrid
                placeholder={"Менеджер"}
                resetTitle={"Все менеджеры"}
                onSelect={(values) => setManagerIds(values.map(({ id }) => id))}
                reset={shouldReset}
              />
              <MultySelect
                data={apps || []}
                isGrid
                placeholder={"Проект"}
                resetTitle={"Все проекты"}
                onSelect={(values) => setAppIds(values.map(({ id }) => id))}
                reset={shouldReset}
              />
            </div>
          </div>
          <div className="flex justify-between items-center">
            <p className="caption-m font-medium opacity-40">
              Найдено {count ? pluralize(count, "сеанс") : "0 сеансов"}
            </p>
            <button className="flex gap-[0.278vw] items-center" onClick={reset}>
              <div className="size-[1.111vw] text-[#7D7D7D]">
                <CloseIcon />
              </div>
              <p className="text-[#7D7D7D] text-[0.972vw] font-medium">
                Сбросить все
              </p>
            </button>
          </div>
        </div>
      </div>
      <div className="space-y-[1.667vw]">
        {isLoading ? (
          <div className="size-[2.222vw] m-auto text-[#7B60F3] animate-spin">
            <SpinIcon />
          </div>
        ) : grouppedSessions?.length ? (
          grouppedSessions?.map(([timestamp, sessions]) => (
            <div key={timestamp} className="space-y-[0.833vw]">
              <p className="caption-m font-medium opacity-40">
                {isToday(new Date(timestamp))
                  ? "Сегодня"
                  : format(new Date(timestamp), "d MMMM", { locale: ru })}
              </p>
              <div className="space-y-[0.278vw]">
                {sessions.map((session) => (
                  <SessionCard key={session.id} session={session} />
                ))}
              </div>
            </div>
          ))
        ) : (
          <div className="m-auto flex flex-col items-center gap-[1.111vw] w-[18.333vw] mt-[6.111vw]">
            <img src="/images/sad_ghost.png" alt="" className="w-[13.889vw]" />
            <div className="space-y-[0.556vw]">
              <p className="text-center font-medium title-m">Ничего не нашли</p>
              <p className="text-[#BDBDBD] caption-s font-medium">
                Попробуйте изменить параметры поиска
              </p>
            </div>
          </div>
        )}
      </div>
      {!!count && (
        <Button
          size="large"
          variant="primary"
          className="w-full"
          onClick={() => setLimit((prev) => prev + 10)}
          disabled={!!count && limit >= count}
        >
          Показать еще
        </Button>
      )}
    </div>
  );
}

export default SessionsPage;
