import { useInvalidate, useWrite } from "@/lib/hooks";
import { ICONS } from "@/theme/icons";
import CopyText from "@/ui/copy-text";
import {
  Button,
  Group,
  Modal,
  PasswordInput,
  Select,
  Stack,
  Text,
  TextInput,
  useMatches,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { useState } from "react";

type ExpiresOptions = "1 day" | "7 days" | "30 days" | "Never";
const ONE_DAY_MS = 1000 * 60 * 60 * 24;

export default function NewOnboardingKey() {
  const [opened, { open, close: _close }] = useDisclosure();
  const [name, setName] = useState("");
  const [privateKey, setPrivateKey] = useState("");
  const [expires, setExpires] = useState<ExpiresOptions>("1 day");

  const [created, setCreated] = useState<{ private_key: string }>();
  const invalidate = useInvalidate();
  const { mutate, isPending } = useWrite("CreateOnboardingKey", {
    onSuccess: ({ private_key }) => {
      notifications.show({ message: "Onboarding Key Created" });
      invalidate(["ListOnboardingKeys"]);
      setCreated({ private_key });
    },
  });
  const now = Date.now();
  const expiresOptions: Record<ExpiresOptions, number> = {
    "1 day": now + ONE_DAY_MS,
    "7 days": now + ONE_DAY_MS * 7,
    "30 days": now + ONE_DAY_MS * 90,
    Never: 0,
  };
  const create = () =>
    mutate({
      name,
      expires: expiresOptions[expires],
      private_key: privateKey || undefined,
    });

  const close = () => {
    setName("");
    setPrivateKey("");
    setExpires("1 day");
    setCreated(undefined);
    _close();
  };

  const size = useMatches({ base: "90%", md: 500 });

  return (
    <>
      <Modal
        opened={opened}
        onClose={close}
        title={
          <Text size="lg">
            {!created && "Create Onboarding Key"}
            {created && "Onboarding Key Created"}
          </Text>
        }
        size={size}
      >
        <Stack>
          {!created && (
            <>
              <Group justify="space-between">
                <Text>Name</Text>
                <TextInput
                  value={name}
                  onChange={(e) => setName(e.target.value)}
                  placeholder="Optional"
                  w={{ base: 200, lg: 300 }}
                />
              </Group>

              <Group justify="space-between">
                <Text>Pre-Existing Key</Text>
                <PasswordInput
                  value={privateKey}
                  onChange={(e) => setPrivateKey(e.target.value)}
                  placeholder="Optional"
                  w={{ base: 200, lg: 300 }}
                />
              </Group>

              <Group justify="space-between">
                <Text>Expiry</Text>
                <Select
                  value={expires}
                  onChange={(expires) => expires && setExpires(expires as any)}
                  data={Object.keys(expiresOptions)}
                  w={{ base: 200, lg: 300 }}
                />
              </Group>

              <Group justify="end">
                <Button
                  variant="secondary"
                  className="gap-4"
                  onClick={create}
                  leftSection={<ICONS.Check size="1rem" />}
                  loading={isPending}
                >
                  Create
                </Button>
              </Group>
            </>
          )}

          {created && (
            <>
              <Text size="md" my="sm">
                Copy the onboarding key below. <b>It won't be shown again</b>.
              </Text>

              <CopyText
                content={created.private_key}
                label="private key"
                w="90%"
              />

              <Group justify="end" onClick={close}>
                <Button leftSection={<ICONS.Clear />}>Close</Button>
              </Group>
            </>
          )}
        </Stack>
      </Modal>

      <Button leftSection={<ICONS.Create size="1rem" />} onClick={open}>
        New Onboarding Key
      </Button>
    </>
  );
}
