import {
  Box,
  Button,
  Card,
  CardBody,
  CardFooter,
  Container,
  Heading,
  HStack,
  Link,
  NumberDecrementStepper,
  NumberIncrementStepper,
  NumberInput,
  NumberInputField,
  NumberInputStepper,
  Select,
  Stack,
  StackDivider,
  Text,
  useToast,
  VStack,
} from "@chakra-ui/react";
import { type LinksFunction } from "@remix-run/cloudflare";
import { type ReactNode, useEffect, useState } from "react";
import stylesheet from "../styles/events-team.css";
import { useLoaderData } from "@remix-run/react";

export const links: LinksFunction = () => {
  return [{ href: stylesheet, rel: "stylesheet" }];
};

export async function loader({ context }: { context: RequestContext }) {
  if (!context.data.current_user)
    throw new Response(null, {
      status: 401,
    });

  if (
    ![1 << 3, 1 << 4, 1 << 12].find(
      (p) => context.data.current_user.permissions & p,
    )
  )
    throw new Response(null, {
      status: 403,
    });

  return await context.data.prisma.etMember.findMany({
    select: {
      id: true,
      name: true,
    },
  });
}

export default function () {
  const memberData = useLoaderData<typeof loader>();
  const [month, setMonth] = useState(new Date().getUTCMonth() + 1);
  const [year, setYear] = useState(new Date().getUTCFullYear());
  const [eventCards, setEventCards] = useState([] as ReactNode[]);
  const toast = useToast();

  async function getEvents() {
    const eventsResp = await fetch(
      `/api/events-team/events/list?month=${month}&year=${year}`,
    ).catch(() => {});

    if (!eventsResp?.ok) {
      let errorMsg = "Unknown error";

      try {
        errorMsg = ((await eventsResp?.json()) as { error: string }).error;
      } catch {}

      toast({
        description: errorMsg,
        status: "error",
        title: "Failed to load events",
      });

      return;
    }

    const eventsData: { [k: string]: any }[] = await eventsResp.json();
    const newEventCards = [];

    for (const event of eventsData) {
      let memberName = event.created_by;
      const memberDataIdx = memberData.findIndex(
        (m) => m.id === event.created_by,
      );

      if (memberDataIdx !== -1)
        memberName = `${memberData[memberDataIdx].name} (${event.created_by})`;

      newEventCards.push(
        <Card w="100%">
          <CardBody>
            <Stack divider={<StackDivider />} spacing="4">
              <Box>
                <Heading size="sm">Date</Heading>
                <Text fontSize="sm" pt="2">
                  {event.year}-{event.month}-{event.day}
                </Text>
              </Box>
              <Box>
                <Heading size="sm">Event Type</Heading>
                <Text fontSize="sm" pt="2">
                  {event.type.toUpperCase()}
                </Text>
              </Box>
              <Box>
                <Heading size="sm">Event Details</Heading>
                <Text fontSize="sm" pt="2">
                  {event.details}
                </Text>
              </Box>
              {event.type === "rotw" ? (
                <Box>
                  <Heading size="sm">Riddle Answer</Heading>
                  <Text fontSize="sm" pt="2">
                    {event.answer}
                  </Text>
                </Box>
              ) : null}
              <Box>
                <Heading size="sm">Host</Heading>
                <Text fontSize="sm" pt="2">
                  {memberName}
                </Text>
              </Box>
            </Stack>
          </CardBody>
          <CardFooter>
            <Text alignSelf="center" fontSize="sm">
              Status:{" "}
              {event.pending
                ? "Not completed"
                : event.approved
                  ? event.performed_at
                    ? "Completed"
                    : "Approved"
                  : "Denied"}
            </Text>
          </CardFooter>
        </Card>,
      );
    }

    setEventCards(newEventCards);
  }

  useEffect(() => {
    (async () => {
      await getEvents();
    })();
  }, []);

  return (
    <Container maxW="container.lg">
      <HStack gap="8px" pb="16px">
        <Select
          onChange={(e) => setMonth(parseInt(e.target.value))}
          value={month}
        >
          <option value={1}>January</option>
          <option value={2}>February</option>
          <option value={3}>March</option>
          <option value={4}>April</option>
          <option value={5}>May</option>
          <option value={6}>June</option>
          <option value={7}>July</option>
          <option value={8}>August</option>
          <option value={9}>September</option>
          <option value={10}>October</option>
          <option value={11}>November</option>
          <option value={12}>December</option>
        </Select>
        <NumberInput
          defaultValue={year}
          max={new Date().getUTCFullYear()}
          onChange={(_, value) => setYear(value)}
          precision={0}
        >
          <NumberInputField />
          <NumberInputStepper>
            <NumberIncrementStepper />
            <NumberDecrementStepper />
          </NumberInputStepper>
        </NumberInput>
        <Button colorScheme="blue" onClick={async () => await getEvents()}>
          Go
        </Button>
      </HStack>
      <VStack spacing="8">{eventCards}</VStack>
      <Link color="#646cff" href="/events-team" mt="16px">
        Back to Current Events
      </Link>
    </Container>
  );
}
