"use client";

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

import { parseAsInteger, useQueryState } from "nuqs";

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

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

import { motion } from "framer-motion";

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

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

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

import { Input } from "@/components/ui/input";
import { Section } from "@/components/section";
import { Button, buttonVariants } from "@/components/ui/button";
import {
  Pagination,
  PaginationContent,
  PaginationItem,
} from "@/components/ui/pagination";

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

import AgentCard from "./agent-card";
import AgentCardSkeleton from "./agent-card-skeleton";
import { Skeleton } from "@/components/ui/skeleton";

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="Search..."
          className="min-w-64 pl-7"
          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-300" />
      </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"
              >
                <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>
              Create new Agent
            </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"
              >
                <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>
              Connect your wallet first
            </Button>
          )}
        </>
      )}
    </motion.div>
  );
}

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

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

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

  const {
    data: agentsData,
    isLoading,
    error,
  } = useQuery({
    queryKey: ["agents", searchFilter, paginationFilter],
    queryFn: async ({ signal }) => {
      const supabase = createClient();

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

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

      return response;
    },
  });

  return (
    <>
      {agentsData && agentsData.data.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(9)].map((_, idx) => (
            <li key={idx}>
              <AgentCardSkeleton />
            </li>
          ))}
        </motion.ul>
      ) : (
        <ul className="px-3 sm:px-6 mb-10 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
          {agentsData &&
            agentsData.data?.map((agent, idx) => (
              <AgentCard key={agent.name} data={agent} idx={idx} user={user} />
            ))}
        </ul>
      )}
      {agentsData ? (
        <Pagination className="mb-8">
          <PaginationContent className="bg-primary rounded-md p-2">
            <PaginationItem>
              <Button
                variant={"outline"}
                size={"icon"}
                disabled={paginationFilter === 0}
                onClick={() => setPaginationFilter((old) => old - 1)}
                className="h-8 w-8"
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>
            </PaginationItem>
            <p className="text-sm font-semibold text-white mx-2">
              Page {paginationFilter + 1} of{" "}
              {agentsData.count
                ? Math.ceil(agentsData.count / DATA_DISPLAY)
                : 1}
            </p>
            <PaginationItem>
              <Button
                variant={"outline"}
                size={"icon"}
                disabled={
                  agentsData.count === 0
                    ? true
                    : paginationFilter + 1 ===
                      Math.ceil(agentsData.count! / DATA_DISPLAY)
                }
                onClick={() => setPaginationFilter((old) => old + 1)}
                className="h-8 w-8"
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
            </PaginationItem>
          </PaginationContent>
        </Pagination>
      ) : null}
    </>
  );
}

export function AgentList() {
  const privyAuth = usePrivy();

  return (
    <section id="agent-list" className="relative z-20">
      <div className="layout border-x">
        <div className="relative w-full overflow-hidden pt-4">
          <AgentListFilter privyAuth={privyAuth} />
        </div>
        <AgentListCards privyAuth={privyAuth} />
      </div>
    </section>
  );
}
