"use client";
import theme from "@/theme";
import {
  Button,
  ChakraProvider,
  Container,
  Flex,
  Heading,
  Image,
  Input,
  Text,
  Box,
  Separator,
} from "@chakra-ui/react";
import { useEffect, useState, useRef } from "react";
import { useSearchParams } from "next/navigation";
import { toaster } from "@/components/ui/toaster";
import { getRandomResultFromGCI, lmgcitfy } from "@/actions";

export default function Home() {
  // state shit
  const [query, setQuery] = useState<string>("");
  const [loading, setLoading] = useState(false);
  const [link, setLink] = useState<string>("");
  // animation refs
  const inputRef = useRef<HTMLInputElement>(null);
  const normalButtonRef = useRef<HTMLButtonElement>(null);
  const luckyButtonRef = useRef<HTMLButtonElement>(null);
  const cursorRef = useRef<HTMLImageElement>(null);
  // query shit
  const passedInParams = useSearchParams();
  const passedInQuery = passedInParams.get("query");
  const isFeelingLucky = passedInParams.get("lucky");
  // handle shit
  const handleGenerateLink = async (feelingLucky: boolean) => {
    if (!query) {
      toaster.error({ description: "You must provide a search query." });
      return;
    }
    const queryParams = new URLSearchParams();

    queryParams.append("query", query);
    try {
      setLoading(true);
      let result: APIResult<string>;
      if (feelingLucky) {
        queryParams.append("lucky", "true");
        result = await getRandomResultFromGCI(query);
      } else {
        result = await lmgcitfy(query);
      }

      if (result.error) {
        toaster.create({
          type: "error",
          title: "Error",
          description: result.errorMessage,
        });
        return;
      }
      setLink(
        `${window.location.protocol}//${window.location.host}/?${queryParams.toString()}`,
      );
    } catch (error) {
      if (error instanceof Error) {
        toaster.error({ description: error.message });
        return;
      }
      toaster.error({ description: "Something went wrong." });
      return;
    } finally {
      setLoading(false);
    }
  };

  const handleCursorMove = () => {
    requestAnimationFrame(() => {
      // we have to stack this because browser paints the first render, then we request twice to paint the third render which applies the necessary changes for the transition (gay)

      requestAnimationFrame(() => {
        const input = inputRef.current!.getBoundingClientRect();
        const inputTargetWidth = input.x + input.width / 3;
        const inputTargetHeight = input.y + input.height / 2;
        cursorRef.current!.style.left = `${inputTargetWidth}px`;
        cursorRef.current!.style.top = `${inputTargetHeight}px`;
      });
    });
  };

  useEffect(() => {
    if (!passedInQuery) {
      return;
    }

    const handleMoveToButton = () => {
      let buttonRef;
      if (isFeelingLucky === "true") {
        buttonRef = luckyButtonRef;
      } else {
        buttonRef = normalButtonRef;
      }

      const boundingRect = buttonRef.current!.getBoundingClientRect();
      const buttonX = boundingRect.x + boundingRect.width / 2;
      const buttonY = boundingRect.y + boundingRect.height / 2;
      cursorRef.current!.style.left = `${buttonX}px`;
      cursorRef.current!.style.top = `${buttonY}px`;

      setTimeout(() => {
        buttonRef.current!.style.scale = `0.95`;
      }, 1250);

      setTimeout(() => {
        buttonRef.current!.style.scale = `1`;
      }, 2350);

      setTimeout(() => {
        toaster.create({
          type: "success",
          title: "LMGCITFY",
          description: "Was that so hard?",
        });
      }, 3000);
    };

    const handleTypingAnimation = () => {
      setTimeout(() => {
        const chars = passedInQuery!.split("");
        let counter = 0;
        const intervalId = setInterval(() => {
          if (inputRef.current!.value.length < chars.length) {
            const splitValue = inputRef.current!.value.split("");
            splitValue.push(chars[counter]);
            inputRef.current!.value = splitValue.join("");
            counter++;
          }
          if (chars.length === inputRef.current!.value.length) {
            clearInterval(intervalId);

            handleMoveToButton();
          }
        }, 75);
      }, 2000);
    };

    const getGCILink = async () => {
      let result: APIResult<string>;
      if (isFeelingLucky === "true") {
        result = await getRandomResultFromGCI(passedInQuery);
      } else {
        result = await lmgcitfy(passedInQuery);
      }
      if (result.error) {
        toaster.create({
          type: "error",
          title: "Error",
          description: result.errorMessage,
        });
        return;
      }
      const link = result.payload;

      setTimeout(() => (window.location.href = link), 9000);
    };
    handleCursorMove();
    handleTypingAnimation();
    getGCILink();
  }, [passedInQuery, isFeelingLucky]);

  return (
    <ChakraProvider value={theme}>
      <Image
        src={"/cursor.png"}
        height={"24px"}
        alt="Fake cursor"
        ref={cursorRef}
        visibility={passedInParams.toString().length > 0 ? "visible" : "hidden"}
        position={"fixed"}
        top={0}
        left={0}
        zIndex={1000}
        transition={"top 2s, left 2s"}
      />
      <Container
        backgroundColor={"#2a2a2a"}
        borderRadius={"lg"}
        boxShadow={"0 0 12px #4a4a4a"}
        py={4}
        width={{ base: "90%", md: "60%" }}
        overflow={"hidden"}
        animationStyle={"scale-fade-in"}
        animationDuration={"slowest"}
      >
        <Flex justify={"center"} align={"center"} p={2} mb={4}>
          <Image
            src={"/gci_logo_large.png"}
            height={{ base: "50px", md: "75px" }}
            alt="GunCAD Index logo"
          />
          <Flex flexDir={"column"} mx={4}>
            <Heading
              size={{ base: "2xl", md: "5xl" }}
              fontFamily={"var(--font-ibm)"}
              lineHeight={1}
            >
              GunCAD Index
            </Heading>
            <Text
              fontSize={{ base: "sm", md: "xl" }}
              ml={{ md: 1 }}
              fontFamily={"var(--font-ibm)"}
            >
              A search engine for guns.
            </Text>
          </Flex>
        </Flex>
        <Input
          variant={"outline"}
          borderRadius={"lg"}
          border={"1px solid #4a4a4a"}
          size={"lg"}
          placeholder="Enter your query here"
          ref={inputRef}
          onChange={(e) => setQuery(e.target.value)}
        />
        <Flex
          justify={"space-around"}
          gapY={4}
          flexDir={{ base: "column", md: "row" }}
          p={2}
          my={4}
        >
          <Button
            colorPalette={"green"}
            variant={"solid"}
            size={"lg"}
            onClick={() => {
              handleGenerateLink(false);
            }}
            loading={loading}
            ref={normalButtonRef}
          >
            Search on GCI
          </Button>
          <Button
            colorPalette={"white"}
            variant={"outline"}
            size={"lg"}
            border={"1px solid #4a4a4a"}
            color={"#FFF"}
            onClick={() => {
              handleGenerateLink(true);
            }}
            loading={loading}
            ref={luckyButtonRef}
          >
            I&apos;m feeling free
          </Button>
        </Flex>
        <Box
          display={link ? "block" : "none"}
          animationStyle={link ? "slide-fade-in" : undefined}
          animationDuration={"slowest"}
        >
          <Separator
            background={
              "linear-gradient(to right, transparent 0%, #FFFFFF60 50%, transparent 100%)"
            }
            mb={4}
            height={"2px"}
          />
          <Flex flexDirection={"column"} gapY={4}>
            <Input
              type="text"
              variant={"subtle"}
              readOnly={true}
              value={link}
              border={"1px solid #4a4a4a"}
            />
            <Button
              variant={"outline"}
              border={"1px solid #4a4a4a"}
              onClick={() => {
                navigator.clipboard.writeText(link);
                toaster.create({ description: "Copied link to clipboard" });
              }}
            >
              Copy Link
            </Button>
          </Flex>
        </Box>
      </Container>
    </ChakraProvider>
  );
}
