import {
  Box,
  Button,
  Card,
  CardBody,
  CardFooter,
  CardHeader,
  Heading,
  Modal,
  ModalBody,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  Stack,
  StackDivider,
  Text,
  Textarea,
  useDisclosure,
  useToast,
} from "@chakra-ui/react";
import { useEffect, useState } from "react";

export default function (props: AppealCardProps & { port?: MessagePort }) {
  const [dateString, setDateString] = useState(
    new Date(props.created_at).toUTCString(),
  );
  const [action, setAction] = useState("");
  const [feedback, setFeedback] = useState("");
  const [loading, setLoading] = useState(false);
  const toast = useToast();

  useEffect(() => {
    setDateString(new Date(props.created_at).toLocaleString());
  }, [props.created_at]);

  const { isOpen, onClose, onOpen } = useDisclosure();

  function showModal(action: "Accept" | "Deny") {
    setAction(action);
    onOpen();
  }

  async function takeAction(action: string) {
    setLoading(true);
    const actionReq = await fetch(`/api/appeals/${props.id}/${action}`, {
      body: feedback ? JSON.stringify({ feedback }) : "{}",
      headers: {
        "content-type": "application/json",
      },
      method: "POST",
    });

    if (actionReq.ok) {
      toast({
        description: `Appeal ${action === "accept" ? "accepted" : "denied"}`,
        duration: 5000,
        status: "success",
        title: "Success",
      });
    } else {
      let error;

      try {
        error = ((await actionReq.json()) as { error: string }).error;
      } catch {
        error = "Unknown error";
      }

      toast({
        description: error,
        duration: 10000,
        status: "error",
        title: "Oops!",
      });
    }

    onClose();
    setFeedback("");
    setAction("");
    setLoading(false);
    props.port?.postMessage(`appeal_${props.id}`);
  }

  return (
    <Card id={`appeal_${props.id}`} key={props.id} w="100%">
      <Modal isOpen={isOpen} onClose={onClose}>
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>{action} this appeal?</ModalHeader>
          <ModalBody>
            <Text size="xs">Optionally provide feedback</Text>
            <Textarea
              onChange={(e) => setFeedback(e.target.value)}
              placeholder="Your feedback"
            />
          </ModalBody>
          <ModalFooter>
            <Button
              onClick={async () => await takeAction(action.toLowerCase())}
              isLoading={loading}
              loadingText="Submitting..."
            >
              Submit
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
      <CardHeader>
        <Heading size="md">Appeal for {props.user.username}</Heading>
        <Text fontSize="xs">ID: {props.user.id}</Text>
      </CardHeader>
      <CardBody>
        <Stack divider={<StackDivider />}>
          <Box>
            <Heading size="xs">Response: Why were you banned?</Heading>
            <Text>{props.ban_reason}</Text>
          </Box>
          <Box>
            <Heading size="xs">Response: Why should we unban you?</Heading>
            <Text>{props.reason_for_unban}</Text>
          </Box>
          <Box>
            <Heading size="xs">
              Response: What have you learned from your mistake?
            </Heading>
            <Text>{props.learned}</Text>
          </Box>
        </Stack>
      </CardBody>
      <CardFooter pb="4px">
        <Box
          display={typeof props.approved === "number" ? "none" : "undefined"}
        >
          <Button colorScheme="red" onClick={() => showModal("Deny")}>
            Deny
          </Button>
          <Button
            colorScheme="blue"
            ml="8px"
            onClick={() => showModal("Accept")}
          >
            Accept
          </Button>
        </Box>
      </CardFooter>
      <CardFooter py="4px">
        <Text fontSize="xs">Submitted at: {dateString}</Text>
      </CardFooter>
    </Card>
  );
}
