import { useState } from 'react';
import {
  ApolloCache,
  FetchResult,
  Reference,
  useMutation,
} from '@apollo/client';
import { ADD_ALLIANCE_MEMBER } from '../schema/mutations';
import {
  AddAllianceMemberMutation,
  AddAllianceMemberMutationVariables,
} from 'types/graphql';
import { call } from 'utils/call';

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

const InvitationSuccessModal = ({
  user,
  onDismiss,
}: {
  user: string;
  onDismiss?: () => void;
}) => {
  return (
    <ModalContainer title="Invitation success">
      <Box spacingY={4}>
        <Text align="center">
          Invitation was sent to the <b>{user}</b>
        </Text>

        <Box display="flex" column spacingY={2}>
          <Button onClick={onDismiss} color="blue">
            Close
          </Button>
        </Box>
      </Box>
    </ModalContainer>
  );
};

const addMemberRef =
  (allianceId: string) =>
  (
    cache: ApolloCache<object>,
    { data }: FetchResult<AddAllianceMemberMutation>
  ) => {
    if (!data?.member) return;
    cache.modify({
      // TODO identify by fragment and id
      id: `Alliance:${allianceId}`,
      fields: {
        members(existingMemberRefs: Reference[]) {
          const updatedMemberRefs = [...existingMemberRefs, data.member];
          return updatedMemberRefs;
        },
      },
    });
  };

interface InviteMemberModalProps {
  allianceId: string;
  onAccept?: () => void;
  onDismiss?: () => void;
  placeholder?: string;
}

export const InviteMemberModal = ({
  allianceId,
  onAccept,
  onDismiss,
  placeholder = 'email@example.com',
}: InviteMemberModalProps) => {
  const [submit, { data, loading, error }] = useMutation<
    AddAllianceMemberMutation,
    AddAllianceMemberMutationVariables
  >(ADD_ALLIANCE_MEMBER, {
    update: addMemberRef(allianceId),
  });

  const [state, setState] = useState({
    username: '',
    message: '',
  });

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

  const handleSubmit: React.FormEventHandler<HTMLFormElement> = async (ev) => {
    ev.preventDefault();
    try {
      const variables = {
        allianceId: allianceId,
        userId: state.username,
        message: state.message,
        role: 'member',
      };
      await submit({ variables });
      call(onAccept);
    } catch (error) {
      console.log(error);
    }
  };

  if (data) {
    return (
      <InvitationSuccessModal user={state.username} onDismiss={onDismiss} />
    );
  }

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