import type { ReactNode } from "react";
import { Suspense, useMemo, useState } from "react";
import { graphql, useLazyLoadQuery } from "react-relay";

import {
  Alert,
  Button,
  Card,
  DocumentationHelp,
  Icon,
  Icons,
  Loading,
  View,
} from "@phoenix/components";
import { useNotifySuccess } from "@phoenix/contexts";
import { getErrorMessagesFromRelayMutationError } from "@phoenix/utils/errorUtils";

import type { UsersCardQuery } from "./__generated__/UsersCardQuery.graphql";
import { NewUserDialog } from "./NewUserDialog";
import { UsersTable } from "./UsersTable";

export function UsersCard() {
  const [fetchKey, setFetchKey] = useState(0);
  const [dialog, setDialog] = useState<ReactNode>(null);
  const [error, setError] = useState<string | null>(null);

  const notifySuccess = useNotifySuccess();

  const isDisabled = useMemo(() => {
    // Disable when no user creation method is available:
    // - Basic auth is disabled AND
    // - No OAuth2 IDPs configured AND
    // - LDAP manual user creation is disabled
    return (
      window.Config.basicAuthDisabled &&
      !window.Config.oAuth2Idps.length &&
      !window.Config.ldapManualUserCreationEnabled
    );
  }, []);

  const data = useLazyLoadQuery<UsersCardQuery>(
    graphql`
      query UsersCardQuery {
        ...UsersTable_users
      }
    `,
    {},
    {
      fetchKey: fetchKey,
      fetchPolicy: "store-and-network",
    }
  );

  return (
    <Card
      title="Users"
      titleExtra={
        <DocumentationHelp topic="userAccess">
          Add users and manage access to this Phoenix instance.
        </DocumentationHelp>
      }
      extra={
        <Button
          onPress={() => {
            setDialog(
              <NewUserDialog
                onDismiss={() => {
                  setDialog(null);
                }}
                onNewUserCreated={(username) => {
                  setDialog(null);
                  notifySuccess({
                    title: "User added",
                    message: `User ${username} has been added.`,
                  });
                  setFetchKey((prev) => prev + 1);
                }}
                onNewUserCreationError={(error) => {
                  const formattedError =
                    getErrorMessagesFromRelayMutationError(error);
                  setError(formattedError?.[0] ?? error.message);
                }}
              />
            );
          }}
          size="S"
          variant="primary"
          leadingVisual={<Icon svg={<Icons.Plus />} />}
          isDisabled={isDisabled}
        >
          Add User
        </Button>
      }
    >
      {error && <Alert variant="danger">{error}</Alert>}
      <Suspense
        fallback={
          <View padding="size-200">
            <Loading />
          </View>
        }
      >
        <UsersTable query={data} />
      </Suspense>
      {dialog}
    </Card>
  );
}
