"use client";

import React, { Fragment } from "react";

import Link from "next/link";
import Image from "next/image";

import { parseAsInteger, useQueryState } from "nuqs";

import { PrivyInterface, usePrivy } from "@privy-io/react-auth";

import { ChevronLeft, ChevronRight, Search } from "lucide-react";

import { motion } from "framer-motion";

import Spline from "@splinetool/react-spline";

import { useInfiniteQuery, useQuery } from "@tanstack/react-query";

import PostgrestError, { ANIMATION_EASE } from "@/lib/config";

import { cn, getRange } from "@/lib/utils";

import { Input } from "@/components/ui/input";
import { Button, buttonVariants } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { Particles } from "@/components/particles";
import { Icons } from "@/components/icons";

import { createClient } from "@/utils/supabase/client";

import AgentCard from "./agent-card";
import AgentCardSkeleton from "./agent-card-skeleton";

import { Swiper, SwiperSlide } from "swiper/react";
import { Autoplay, EffectCoverflow, Navigation } from "swiper/modules";
import "swiper/css";
import "swiper/css/effect-coverflow";
import "swiper/css/pagination";
import "swiper/css/navigation";
import "swiper/css/navigation";

const DATA_DISPLAY = 9;

function AgentListFilter({ privyAuth }: { privyAuth: PrivyInterface }) {
  const { ready, authenticated } = privyAuth;

  const [searchFilter, setSearchFilter] = useQueryState("search", {
    defaultValue: "",
    throttleMs: 1000,
    shallow: false,
    history: "push",
  });

  const [_, setPaginationFilter] = useQueryState(
    "page",
    parseAsInteger
      .withOptions({
        shallow: false,
        history: "push",
        scroll: false,
      })
      .withDefault(0)
  );

  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.8, ease: ANIMATION_EASE }}
      className="pt-1 px-3 sm:px-6 mb-8 flex flex-col sm:flex-row gap-3 justify-between"
    >
      <div className="relative">
        <Input
          aria-label="search"
          id="search"
          type="search"
          placeholder=">>>_Awaiting input..."
          className="min-w-64 pl-7 border-primary rounded-none"
          value={searchFilter}
          onChange={(e) => {
            setPaginationFilter(0);
            e.target.value === ""
              ? setSearchFilter(null)
              : setSearchFilter(e.target.value);
          }}
        />
        <Search className="absolute w-4 h-4 left-2 top-1/2 -translate-y-1/2 text-gray-400" />
      </div>
      {!ready ? (
        <Skeleton className="h-10 w-32" />
      ) : (
        <>
          {authenticated ? (
            <Link
              href={`/agents/create`}
              className={cn(
                buttonVariants({ variant: "default" }),
                "w-full sm:w-auto text-background flex gap-2"
              )}
            >
              <svg
                width="24"
                height="24"
                viewBox="0 0 24 24"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
                className="mr-2"
              >
                <path
                  fillRule="evenodd"
                  clipRule="evenodd"
                  d="M6.55189 0.333435H17.4369C21.4036 0.333435 23.6669 2.57343 23.6669 6.55177V17.4484C23.6669 21.4034 21.4152 23.6668 17.4486 23.6668H6.55189C2.57356 23.6668 0.333557 21.4034 0.333557 17.4484V6.55177C0.333557 2.57343 2.57356 0.333435 6.55189 0.333435ZM12.9569 12.9684H16.2702C16.8069 12.9568 17.2386 12.5251 17.2386 11.9884C17.2386 11.4518 16.8069 11.0201 16.2702 11.0201H12.9569V7.7301C12.9569 7.19344 12.5252 6.76177 11.9886 6.76177C11.4519 6.76177 11.0202 7.19344 11.0202 7.7301V11.0201H7.71856C7.46189 11.0201 7.21689 11.1251 7.03022 11.3001C6.85522 11.4868 6.75022 11.7306 6.75022 11.9884C6.75022 12.5251 7.18189 12.9568 7.71856 12.9684H11.0202V16.2701C11.0202 16.8068 11.4519 17.2384 11.9886 17.2384C12.5252 17.2384 12.9569 16.8068 12.9569 16.2701V12.9684Z"
                  fill="white"
                />
              </svg>
              <Icons.paranthesesLeft />
              <span className="">Create new Agent</span>
              <Icons.paranthesesRight />
            </Link>
          ) : (
            <Button
              disabled
              className="w-full sm:w-auto text-background flex gap-2"
            >
              <svg
                width="24"
                height="24"
                viewBox="0 0 24 24"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
                className="mr-2"
              >
                <path
                  fillRule="evenodd"
                  clipRule="evenodd"
                  d="M6.55189 0.333435H17.4369C21.4036 0.333435 23.6669 2.57343 23.6669 6.55177V17.4484C23.6669 21.4034 21.4152 23.6668 17.4486 23.6668H6.55189C2.57356 23.6668 0.333557 21.4034 0.333557 17.4484V6.55177C0.333557 2.57343 2.57356 0.333435 6.55189 0.333435ZM12.9569 12.9684H16.2702C16.8069 12.9568 17.2386 12.5251 17.2386 11.9884C17.2386 11.4518 16.8069 11.0201 16.2702 11.0201H12.9569V7.7301C12.9569 7.19344 12.5252 6.76177 11.9886 6.76177C11.4519 6.76177 11.0202 7.19344 11.0202 7.7301V11.0201H7.71856C7.46189 11.0201 7.21689 11.1251 7.03022 11.3001C6.85522 11.4868 6.75022 11.7306 6.75022 11.9884C6.75022 12.5251 7.18189 12.9568 7.71856 12.9684H11.0202V16.2701C11.0202 16.8068 11.4519 17.2384 11.9886 17.2384C12.5252 17.2384 12.9569 16.8068 12.9569 16.2701V12.9684Z"
                  fill="white"
                />
              </svg>
              <Icons.paranthesesLeft />
              <span className="">Create new Agent</span>
              <Icons.paranthesesRight />
            </Button>
          )}
        </>
      )}
    </motion.div>
  );
}

function AgentListCards({ privyAuth }: { privyAuth: PrivyInterface }) {
  const { user } = privyAuth;

  const [searchFilter] = useQueryState("search", {
    defaultValue: "",
    throttleMs: 1000,
    shallow: false,
    history: "push",
  });

  const {
    data: agentsData,
    isLoading,
    error,
    isFetchingNextPage,
    hasNextPage,
    fetchNextPage,
  } = useInfiniteQuery({
    queryKey: ["agents", searchFilter],
    queryFn: async ({ signal, pageParam }) => {
      const range = getRange(pageParam, DATA_DISPLAY);

      const supabase = createClient();

      const response = await supabase
        .from("agents")
        .select("*", { count: "exact" })
        .ilike("name", `%${searchFilter}%`)
        .order("id", { ascending: false })
        .range(range[0], range[1]);

      if (response.error) throw new PostgrestError(response.error);

      return response;
    },
    initialPageParam: 0,
    getNextPageParam: (lastPage, allPages) => {
      // console.log({ lastPage, allPages });

      if (!lastPage.count) return undefined;

      const nextPage: number | undefined =
        allPages.length * DATA_DISPLAY < lastPage.count
          ? allPages?.length
          : undefined;

      return nextPage;
    },
  });

  return (
    <>
      {agentsData && agentsData.pages.length === 0 && (
        <div className="flex flex-col justify-center items-center ">
          <figure className="relative w-full sm:w-1/2 h-72 sm:h-96 mb-6">
            <Image
              className="object-cover"
              src="/empty-data.jpg"
              fill={true}
              alt="Empty data"
            />
          </figure>
          <h1 className="text-xl font-bold">No data found</h1>
        </div>
      )}
      {isLoading ? (
        <motion.ul
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.8, ease: ANIMATION_EASE }}
          className="px-3 sm:px-6 mb-10 grid grid-cols-1 lg:grid-cols-3 gap-6"
        >
          {[...Array(3)].map((_, idx) => (
            <li key={idx}>
              <AgentCardSkeleton />
            </li>
          ))}
        </motion.ul>
      ) : (
        <>
          {agentsData && (
            <div className="relative mb-8">
              <Swiper
                spaceBetween={50}
                effect={"coverflow"}
                centeredSlides={true}
                allowTouchMove={false}
                slidesPerView={1}
                coverflowEffect={{
                  rotate: 0,
                  stretch: 0,
                  depth: 100,
                  modifier: 2.5,
                }}
                pagination={true}
                navigation={{
                  prevEl: "#prev-button",
                  nextEl: "#next-button",
                }}
                breakpoints={{
                  720: {
                    slidesPerView: 2,
                  },
                  1024: {
                    slidesPerView: 3,
                  },
                }}
                onReachEnd={(swiper) => {
                  if (hasNextPage) fetchNextPage();
                }}
                modules={[EffectCoverflow, Autoplay, Navigation]}
              >
                {agentsData.pages.map((page, idx) => (
                  <Fragment key={idx}>
                    {page.data.map((agent, idx2) => (
                      <SwiperSlide key={agent.id}>
                        {({ isActive }) => (
                          <AgentCard
                            key={agent.name}
                            data={agent}
                            user={user}
                            isActive={isActive}
                          />
                        )}
                      </SwiperSlide>
                    ))}
                  </Fragment>
                ))}
                {isFetchingNextPage && (
                  <SwiperSlide>
                    <AgentCardSkeleton />
                  </SwiperSlide>
                )}
              </Swiper>
              <ul
                role="group"
                className="absolute top-1/2 z-10 w-full flex justify-between -translate-y-full"
              >
                <SwiperButton variant="prev" />
                <SwiperButton variant="next" />
              </ul>
            </div>
          )}
        </>
      )}
    </>
  );
}

export function AgentList() {
  const [showCirlce, setShowCircle] = React.useState(true);

  const privyAuth = usePrivy();

  const swiperCss = `
    .swiper{
      width: 90%;
    }
    .swiper-3d .swiper-slide-shadow-left {
      background-image: none;
    }
    .swiper-3d .swiper-slide-shadow-right{
      background: none;
    }
  `;

  return (
    <>
      <style>{swiperCss}</style>
      <section id="agent-list" className="relative z-20">
        <div className="layout">
          {showCirlce ? (
            <motion.div className="flex flex-col items-center">
              <div className=" h-[460px] w-[580px] mb-8">
                <Spline scene="https://prod.spline.design/KfOmDzJBqmDFKlzQ/scene.splinecode" />
              </div>
              <Button size={"lg"} onClick={() => setShowCircle(false)}>
                Agent List
              </Button>
            </motion.div>
          ) : (
            <>
              <div className="relative w-full overflow-hidden pt-4">
                <AgentListFilter privyAuth={privyAuth} />
              </div>
              <AgentListCards privyAuth={privyAuth} />
            </>
          )}
        </div>
      </section>
      {!showCirlce && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{
            ease: ANIMATION_EASE,
          }}
        >
          <Particles
            className="absolute inset-0 z-0 opacity-30"
            quantity={5000}
            ease={90}
            color={"#000000"}
            refresh
          />
        </motion.div>
      )}
    </>
  );
}

function SwiperButton({ variant }: { variant: "prev" } | { variant: "next" }) {
  return (
    <Button
      id={variant === "prev" ? "prev-button" : "next-button"}
      className={cn("px-0 py-8")}
    >
      {variant === "prev" ? <ChevronLeft /> : <ChevronRight />}
    </Button>
  );
}
