import {
  Alert,
  AlertIcon,
  Box,
  Button,
  Card,
  CardBody,
  CardHeader,
  Center,
  Container,
  Heading,
  HStack,
  Image,
  Input,
  Link,
  Stack,
  StackDivider,
  Text,
  useToast,
} from "@chakra-ui/react";
import { type FormEvent, type ReactElement, useState } from "react";

export async function loader({ context }: { context: RequestContext }) {
  const { current_user: currentUser } = context.data;

  if (!currentUser)
    throw new Response(null, {
      status: 401,
    });

  if (
    !(currentUser.permissions & (1 << 5)) &&
    !(currentUser.permissions & (1 << 8))
  )
    throw new Response(null, {
      status: 403,
    });

  return null;
}

export function meta() {
  return [{ title: "Hammer - Car Crushers" }];
}

export default function () {
  const [username, setUsername] = useState("");
  const [uid, setUid] = useState("");
  const [status, setStatus] = useState("");
  const [visible, setVisible] = useState(false);
  const [avatarUrl, setAvatarUrl] = useState("");
  const [history, setHistory] = useState([] as ReactElement[]);
  const [hasResults, setHasResults] = useState(true);
  const [loading, setLoading] = useState(false);
  const toast = useToast();

  async function getHistory() {
    setVisible(false);
    setLoading(true);
    setHistory([]);

    if (username.length < 4) {
      setLoading(false);
      return toast({
        title: "Validation Error",
        description: `Username is too short`,
        status: "error",
      });
    }

    const historyResp = await fetch(`/api/game-bans/${username}/history`);

    if (!historyResp.ok) {
      setLoading(false);
      return toast({
        title: "Failed To Fetch User",
        description: `${
          ((await historyResp.json()) as { error: string }).error
        }`,
        status: "error",
      });
    }

    const {
      history,
      user,
    }: {
      history: { [k: string]: any }[];
      user: { avatar: string | null; id: number; name: string };
    } = await historyResp.json();

    if (!history.length) {
      setLoading(false);
      setHasResults(false);
      return toast({
        title: "Nothing Found",
        description: "This user doesn't have any moderation history.",
        status: "info",
      });
    }

    setHasResults(true);
    const cardList = [];

    setAvatarUrl(user.avatar ?? "https://i.hep.gg/floppa");
    setUid(user.id.toString());
    setStatus(history[history.length - 1].entity.properties.action.stringValue);

    for (const entry of history) {
      const url = entry.entity.properties.evidence.stringValue;
      const isUrl = () => {
        try {
          new URL(url).href;
          return true;
        } catch {
          return false;
        }
      };

      cardList.push(
        <Container mb={3}>
          <Card>
            <CardHeader>
              <Heading size="md">
                {new Date(
                  parseInt(entry.entry.properties.executed_at.integerValue),
                ).toLocaleString()}
              </Heading>
            </CardHeader>
            <CardBody>
              <Stack divider={<StackDivider />} spacing="4">
                <Box>
                  <Heading size="xs">ACTION</Heading>
                  <Text pt="2" size="sm">
                    {entry.entity.properties.action.stringValue}
                  </Text>
                </Box>
                <Box>
                  <Heading size="xs">EVIDENCE</Heading>
                  <Text pt="2" size="sm">
                    {isUrl() ? (
                      <Link color="#646cff" href={url}>
                        {url}
                      </Link>
                    ) : (
                      url
                    )}
                  </Text>
                </Box>
              </Stack>
            </CardBody>
          </Card>
        </Container>,
      );
    }

    setHistory(cardList);
    setLoading(false);
    setVisible(true);
  }

  return (
    <Container maxW="container.md">
      <Heading>User Lookup</Heading>
      <Text>Look up a user's punishment history here.</Text>
      {!hasResults ? (
        <Alert status="warning" mt={2}>
          <AlertIcon />
          No information was found for this user. Perhaps you misspelt their
          name?
        </Alert>
      ) : null}
      <HStack mt={5}>
        <Input
          id="username"
          onBeforeInput={(e) => {
            const { data }: { data?: string } & FormEvent<HTMLInputElement> = e;

            if (data?.match(/\W/)) e.preventDefault();
          }}
          onChange={(e) => setUsername(e.target.value)}
          placeholder="Roblox username"
        />
        <Button
          ml="8px"
          onClick={async () => await getHistory()}
          isLoading={loading}
        >
          Search
        </Button>
      </HStack>
      <Center mb={3} mt={3}>
        <Card maxW="md" visibility={visible ? "visible" : "hidden"}>
          <CardBody>
            <Image mb="16" src={avatarUrl} />
            <Stack divider={<StackDivider />} spacing="6">
              <Box>
                <Heading size="xs">USERNAME</Heading>
                <Text pt="2" fontSize="sm">
                  {username}
                </Text>
              </Box>
              <Box>
                <Heading size="xs">USER ID</Heading>
                <Text pt="2" fontSize="sm">
                  {uid}
                </Text>
              </Box>
              <Box>
                <Heading size="xs">MODERATION STATUS</Heading>
                <Text pt="2" fontSize="sm">
                  {status}
                </Text>
              </Box>
            </Stack>
          </CardBody>
        </Card>
      </Center>
      {history}
    </Container>
  );
}
