import calendarStyles from "react-big-calendar/lib/css/react-big-calendar.css";
import calendarOverrides from "../styles/calendar.css";
import eventStyles from "../styles/events-team.css";
import { Calendar, dayjsLocalizer } from "react-big-calendar";
import dayjs from "dayjs";
import { type LinksFunction } from "@remix-run/cloudflare";
import {
  Button,
  Container,
  Flex,
  Heading,
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  Popover,
  PopoverArrow,
  PopoverBody,
  PopoverCloseButton,
  PopoverContent,
  PopoverHeader,
  PopoverTrigger,
  Spacer,
  Text,
  useDisclosure,
  VStack,
} from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
import { useState } from "react";
import utc from "dayjs/plugin/utc.js";
import { EtMember } from "../../generated/prisma/client.js";

export const links: LinksFunction = () => {
  return [
    { href: calendarStyles, rel: "stylesheet" },
    { href: eventStyles, rel: "stylesheet" },
    { href: calendarOverrides, 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,
    });

  const now = new Date();
  const eventsData = await context.data.prisma.event.findMany({
    orderBy: {
      day: "asc",
    },
    select: {
      answer: true,
      approved: true,
      created_by: true,
      day: true,
      details: true,
      id: true,
      month: true,
      pending: true,
      performed_at: true,
      reached_minimum_player_count: true,
      type: true,
      year: true,
    },
    where: {
      month: now.getUTCMonth() + 1,
      year: now.getUTCFullYear(),
    },
  });

  const calendarData = eventsData.map((e) => {
    return {
      id: e.id,
      title: (e.type as string).toUpperCase(),
      allDay: true,
      // A Date object will not survive being passed to the client
      start: `${e.year}-${(e.month as number).toString().padStart(2, "0")}-${(e.day as number).toString().padStart(2, "0")}T00:00:00.000Z`,
      end: `${e.year}-${(e.month as number).toString().padStart(2, "0")}-${(e.day as number).toString().padStart(2, "0")}T00:00:00.000Z`,
    };
  });

  const memberData = await context.data.prisma.$queryRaw<
    EtMember[]
  >`SELECT id, name FROM et_members WHERE id IN (SELECT created_by FROM events WHERE month = ${now.getUTCMonth() + 1} AND year = ${now.getUTCFullYear()});`;

  return {
    calendarData,
    canManage: Boolean(
      [1 << 4, 1 << 12].find((p) => context.data.current_user.permissions & p),
    ),
    eventList: eventsData,
    memberData,
  };
}

export default function () {
  const data = useLoaderData<typeof loader>();
  const [eventData, setEventData] = useState({} as { [k: string]: any });
  const { isOpen, onClose, onOpen } = useDisclosure();

  dayjs.extend(utc);

  return (
    <Container maxW="container.lg" h="600px">
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Event Info</ModalHeader>
          <ModalCloseButton />
          <ModalBody>
            <Heading size="md">Host</Heading>
            <Text>
              {data.memberData.find((m) => m.id === eventData.created_by)?.name}
            </Text>
            <br />
            <Heading size="md">Event Type</Heading>
            <Text>{eventData?.type?.toUpperCase()}</Text>
            <br />
            <Heading size="md">Details</Heading>
            <Text>{eventData?.details}</Text>
            <br />
            {eventData?.type === "rotw" ? (
              <>
                <Heading size="md">Answer</Heading>
                <Text>{eventData.answer}</Text>
              </>
            ) : null}
          </ModalBody>
          <ModalFooter>
            <Button onClick={onClose}>Close</Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
      <Calendar
        endAccessor={(event) => new Date(event.end)}
        events={data.calendarData}
        localizer={dayjsLocalizer(dayjs)}
        onSelectEvent={(e) => {
          setEventData(
            data.eventList.find((ev) => ev.id === e.id) as { [k: string]: any },
          );
          onOpen();
        }}
        popup
        startAccessor={(event) => new Date(event.start)}
        style={{ height: 500 }}
        toolbar={false}
        views={["month"]}
      />
      <Flex mt="16px">
        <Button as="a" colorScheme="blue" href="/book-event">
          Book Event
        </Button>
        <Spacer />
        {data.canManage ? (
          <Popover placement="top-end">
            <PopoverTrigger>
              <Button colorScheme="blue">Management</Button>
            </PopoverTrigger>
            <PopoverContent>
              <PopoverHeader fontWeight="semibold">
                Management Tools
              </PopoverHeader>
              <PopoverArrow />
              <PopoverCloseButton />
              <PopoverBody>
                <VStack>
                  <Button as="a" href="/events-team/historical" w="100%">
                    Historical Events
                  </Button>
                  <Button as="a" href="/et-members" w="100%">
                    Member Management
                  </Button>
                  <Button as="a" href="/events-team/outstanding" w="100%">
                    Outstanding Events
                  </Button>
                </VStack>
              </PopoverBody>
            </PopoverContent>
          </Popover>
        ) : null}
      </Flex>
    </Container>
  );
}
