import {
  Alert,
  AlertDescription,
  AlertIcon,
  AlertTitle,
  Box,
  Button,
  Container,
  Flex,
  Heading,
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  Spacer,
  Text,
  Textarea,
  useDisclosure,
  useToast,
} from "@chakra-ui/react";
import { useLoaderData } from "@remix-run/react";
import { useState } from "react";
import Success from "../../components/Success.js";

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

  const { current_user: currentUser } = context.data;
  const dataKV = context.env.DATA;
  const disabled = await dataKV.get("appeal_disabled");

  return {
    can_appeal:
      !Boolean(disabled) &&
      !Boolean(await dataKV.get(`blockedappeal_${currentUser.id}`)) &&
      !Boolean(
        await context.env.D1.prepare(
          "SELECT * FROM appeals WHERE open = 1 AND user = ? LIMIT 1;",
        )
          .bind(currentUser.id)
          .first(),
      ),
    can_toggle:
      currentUser.permissions & (1 << 0) || currentUser.permissions & (1 << 11),
    disabled: Boolean(disabled),
  };
}

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

export default function () {
  const pageProps = useLoaderData<typeof loader>();
  const { isOpen, onClose, onOpen } = useDisclosure();
  const [showSuccess, setShowSuccess] = useState(false);
  const [loading, setLoading] = useState(false);
  const toast = useToast();

  async function submit() {
    setLoading(true);
    const learned = (document.getElementById("learned") as HTMLInputElement)
      .value;
    const whyBanned = (document.getElementById("whyBanned") as HTMLInputElement)
      .value;
    const whyUnban = (document.getElementById("whyUnban") as HTMLInputElement)
      .value;

    const submitReq = await fetch("/api/appeals/submit", {
      body: JSON.stringify({
        learned,
        whyBanned,
        whyUnban,
      }),
      headers: {
        "content-type": "application/json",
      },
      method: "POST",
    }).catch(() => {});

    if (!submitReq) {
      setLoading(false);
      return toast({
        description: "Please check your internet and try again",
        duration: 10000,
        isClosable: true,
        status: "error",
        title: "Request Failed",
      });
    }

    if (!submitReq.ok) {
      setLoading(false);
      return toast({
        description: ((await submitReq.json()) as { error: string }).error,
        duration: 10000,
        isClosable: true,
        status: "error",
        title: "Error",
      });
    }

    setShowSuccess(true);
    setLoading(false);
  }

  async function toggle(active: boolean) {
    const toggleReq = await fetch("/api/appeals/toggle", {
      body: JSON.stringify({ active }),
      headers: {
        "content-type": "application/json",
      },
      method: "POST",
    });

    if (!toggleReq.ok)
      return toast({
        description: ((await toggleReq.json()) as { error: string }).error,
        duration: 10000,
        isClosable: true,
        status: "error",
        title: "Error",
      });

    toast({
      description: `The appeals form is now ${active ? "opened" : "closed"}.`,
      isClosable: true,
      status: "success",
      title: `Appeals ${active ? "enabled" : "disabled"}`,
    });

    onClose();
    pageProps.can_appeal = !pageProps.can_appeal;
    pageProps.disabled = !pageProps.disabled;
  }

  return showSuccess ? (
    <Success
      heading="Appeal Submitted"
      message="You will receive an email when we reach a decision."
    />
  ) : (
    <Container maxW="container.md" pt="4vh" textAlign="start">
      <Alert
        borderRadius="8px"
        display={pageProps.disabled ? "flex" : "none"}
        mb="16px"
        status="error"
      >
        <AlertIcon />
        <Box>
          <AlertTitle>Appeals Closed</AlertTitle>
          <AlertDescription>
            We are currently not accepting appeals.
          </AlertDescription>
        </Box>
      </Alert>
      <Flex>
        <Spacer />
        <Button display={pageProps.can_toggle ? "" : "none"} onClick={onOpen}>
          {pageProps.disabled ? "Enable" : "Disable"} Appeals
        </Button>
      </Flex>
      <br />
      <Modal isCentered isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Toggle appeals?</ModalHeader>
          <ModalCloseButton />
          <ModalBody>
            <Text>
              Are you sure you want to{" "}
              {pageProps.disabled ? "enable" : "disable"} appeals?
            </Text>
          </ModalBody>
          <ModalFooter style={{ gap: "8px" }}>
            <Button onClick={onClose} variant="ghost">
              No
            </Button>
            <Button
              onClick={async () => await toggle(pageProps.disabled)}
              variant="danger"
            >
              Yes
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
      <Heading size="xl">Discord Appeals</Heading>
      <br />
      <Text fontSize="md">
        This is for Discord bans only! See the support page if you were banned
        from the game.
      </Text>
      <br />
      <br />
      <Heading size="md">Why were you banned?</Heading>
      <br />
      <Textarea
        disabled={!pageProps.can_appeal}
        id="whyBanned"
        maxLength={500}
        placeholder="Your response"
      />
      <br />
      <br />
      <br />
      <Heading size="md">Why should we unban you?</Heading>
      <br />
      <Textarea
        disabled={!pageProps.can_appeal}
        id="whyUnban"
        maxLength={2000}
        placeholder="Your response"
      />
      <br />
      <br />
      <br />
      <Heading size="md">What have you learned from your mistake?</Heading>
      <br />
      <Textarea
        disabled={!pageProps.can_appeal}
        id="learned"
        maxLength={2000}
        placeholder="Your response"
      />
      <br />
      <br />
      <Button
        disabled={pageProps.can_appeal}
        onClick={async () => await submit()}
        loadingText="Submitting"
        isLoading={loading}
      >
        Submit
      </Button>
    </Container>
  );
}