import { useState } from 'react';
import {
  ApolloCache,
  FetchResult,
  Reference,
  useMutation,
  gql,
} from '@apollo/client';
import { workspace } from '../schema/fragments';
import {
  CreateWorkspaceMutation,
  CreateWorkspaceMutationVariables,
} from 'types/graphql';
import { handleGraphQLError } from 'lib/appsync/utils';
import { QUOTA_EXCEEDED_EXCEPTION } from 'lib/appsync/errorTypes';
import { call } from 'utils/call';

import { Box, Button, Spinner, Text } from 'components/common';
import { Input } from 'components/inputs';
import { ModalContainer } from 'components/modals';

import { UpgradeSubscriptionModal } from 'components/billing/modals';

const CREATE_WORKSPACE = gql`
  mutation CREATE_WORKSPACE($name: String!, $description: String) {
    workspace: createWorkspace(name: $name, description: $description) {
      ...workspace
    }
  }
  ${workspace}
`;

const updateCacheWithNewWorkspace = (
  cache: ApolloCache<any>,
  { data }: FetchResult<CreateWorkspaceMutation>
) => {
  if (!data?.workspace) return;
  cache.modify({
    fields: {
      allWorkspaces(existingWorkspaceRefs: Reference[]) {
        const newWorkspaceRef = cache.writeFragment({
          data: data.workspace,
          fragment: workspace,
          fragmentName: 'workspace',
        });

        return [...existingWorkspaceRefs, newWorkspaceRef];
      },
    },
  });
};

interface CreateWorkspaceModalProps {
  onDismiss?: () => void;
}

type SubmitHandler = {
  (event: React.FormEvent<HTMLFormElement>): void;
  (event: React.MouseEvent<HTMLButtonElement>): void;
};

export const CreateWorkspaceModal = ({
  onDismiss,
}: CreateWorkspaceModalProps) => {
  const [state, setState] = useState({
    name: '',
    // description: '',
  });

  const [create, { loading, error }] = useMutation<
    CreateWorkspaceMutation,
    CreateWorkspaceMutationVariables
  >(CREATE_WORKSPACE, { update: updateCacheWithNewWorkspace });

  const handleChange: React.ChangeEventHandler<HTMLInputElement> = (ev) => {
    const { name, value } = ev.target;
    setState((s) => ({ ...s, [name]: value }));
  };

  const handleSubmit: SubmitHandler = async (ev) => {
    ev.preventDefault();

    try {
      const { data } = await create({
        variables: state,
      });
      if (data?.workspace) {
        call(onDismiss);
      }
    } catch (error) {
      console.error(error);
    }
  };

  const exception = handleGraphQLError(error, QUOTA_EXCEEDED_EXCEPTION);
  if (exception) {
    return (
      <UpgradeSubscriptionModal
        message={exception.message}
        onDismiss={onDismiss}
      />
    );
  }

  return (
    <ModalContainer title="Create workspace">
      <form onSubmit={handleSubmit}>
        <Box position="relative" spacingY={2}>
          <Input
            name="name"
            value={state.name}
            onChange={handleChange}
            placeholder="Workspace name"
            onFocus={(ev) => ev.target.select()}
            autoFocus
            disabled={loading}
          />
          {/* <textarea
            rows={4}
            className="input"
            name="description"
            value={state.description}
            onChange={handleChange}
            placeholder="Description"
            disabled={loading}
          /> */}
          <Spinner show={loading} />
        </Box>
        <Box display="flex" marginY={4} spacing={2}>
          {onDismiss && (
            <Button type="button" onClick={onDismiss} color="gray" block>
              Cancel
            </Button>
          )}
          <Button
            type="submit"
            onClick={handleSubmit}
            color="blue"
            block
            disabled={!state.name || loading}
          >
            Create
          </Button>
        </Box>
      </form>
      {error && (
        <Text size="s" align="center">
          Something went wrong
        </Text>
      )}
    </ModalContainer>
  );
};
