import React from "react";
import { useUserContext } from "./UserContext";
import {
  Avatar,
  Box,
  Button,
  Checkbox,
  Fieldset,
  Flex,
  Modal,
  Paper,
  TextInput,
  Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { Link, useLoaderData } from "react-router";
import { useForm } from "@mantine/form";
import { notifications } from "@mantine/notifications";
import { fetchHeaders } from "./fetch";

const RE_MASTODON_ACCOUNTS = /^(@(\w+)(@([\w\.]+))? )*(@\w+)(@[\w\.]+)?$/;

export const AuthorizeMastodonModal: React.FC<{
  opened: boolean;
  onClose: () => void;
}> = ({ opened, onClose }) => {
  const [serverName, setServerName] = React.useState("rubber.social");
  const [loading, setLoading] = React.useState(false);

  const handleClick = React.useCallback(() => {
    setLoading(true);
    fetch(`/api/mastodon_oauth?server=${encodeURI(serverName)}`)
      .then((response) => response.json())
      .then((json) => {
        if (json["url"]) {
          window.location.href = json["url"];
        }
      });
  }, []);

  return (
    <Modal opened={opened} onClose={onClose} title="Authorize with Mastodon">
      <TextInput
        label="Server Domain"
        value={serverName}
        onChange={(event) => setServerName(event.currentTarget.value)}
      />
      <Button loading={loading} onClick={handleClick}>
        Authorize
      </Button>
    </Modal>
  );
};

type MastodonPreferencesForm = {
  attn_list?: string;
  post_public?: boolean;
};

export const profileLoader = async () =>
  fetch(`/api/me`).then((response) => response.json());

export const Profile: React.FC = () => {
  const { username, telegram_photo_url, mastodon_server, mastodon_username } =
    useUserContext();
  const { mastodon_attn_list, mastodon_post_public } = useLoaderData<{
    mastodon_attn_list?: string;
    mastodon_post_public?: boolean;
  }>();
  const [opened, { open, close }] = useDisclosure(false);

  const mastodon_account = React.useMemo(
    () =>
      mastodon_username && mastodon_server
        ? `@${mastodon_username}@${mastodon_server}`
        : null,
    [mastodon_server, mastodon_username],
  );

  const [loading, setLoading] = React.useState(false);
  const form = useForm<MastodonPreferencesForm>({
    mode: "uncontrolled",
    initialValues: {
      attn_list: mastodon_attn_list,
      post_public: mastodon_post_public,
    },
    validate: {
      attn_list: (value: string) =>
        !value || RE_MASTODON_ACCOUNTS.test(value)
          ? null
          : "Please enter a valid list of accounts",
    },
  });

  const handleSubmit = React.useCallback(
    form.onSubmit((values) => {
      setLoading(true);
      fetch(`/api/profile`, {
        method: "POST",
        headers: fetchHeaders(),
        body: JSON.stringify(values),
      })
        .then((response) => {
          if (response.ok) {
            notifications.show({
              title: "Success",
              message: "Your preferences have been saved",
              color: "green",
            });
          } else {
            notifications.show({
              title: "Error",
              message: "There was a problem saving your preferences",
              color: "red",
            });
          }
        })
        .finally(() => {
          setLoading(false);
        });
    }),
    [],
  );

  return (
    <>
      <Flex align="center" gap="md" mb="xl">
        <Avatar src={telegram_photo_url} size="150" />
        <Title>{username}</Title>
      </Flex>
      <Box mb="md">
        <Link to={`/dashboard`}>Return to dashboard</Link>
      </Box>
      <Paper bg="gray.1">
        <Title order={4}>Mastodon</Title>
        <TextInput label="Account" w="50%" value={mastodon_account} />
        <Button onClick={open}>Authorize with Mastodon</Button>
        <AuthorizeMastodonModal opened={opened} onClose={close} />
        <Fieldset legend="Preferences" my="lg">
          <form onSubmit={handleSubmit}>
            <Checkbox
              {...form.getInputProps("post_public", { type: "checkbox" })}
              label="Post orders publically"
              mb="md"
            />
            <TextInput
              {...form.getInputProps("attn_list")}
              label="Tag Accounts"
              w="50%"
              description="Additional accounts to tag with your orders"
            />
            <Button type="submit" loading={loading} mt="md">
              Save
            </Button>
          </form>
        </Fieldset>
      </Paper>
    </>
  );
};
