import React, { useEffect, useState } from 'react';

import { Box, Grid, GridItem, Input, Text, Checkbox, MainButton } from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import { inject } from 'mobx-react';
import { useTranslation } from 'utils/i18n';
import { useApolloClient, useMutation, useQuery } from '@apollo/client';
import { IProfile, IUserData } from 'typings';
import Authentication from 'store/authentication';
import { UPDATE_SUBSCRIPTION } from 'graphql/mutations/subscription';
import { SUBSCRIPTIONUSER } from 'graphql/queries/subscriptionUser';
import { KENNITALA } from 'graphql/queries/kennitala';
import { useSnackbar } from 'notistack';

interface IUserSettingsProps {
  subscriptionId?: string;
  color: MainColorType;
  authentication: Authentication;
}

export const UserSettings = ({ color, subscriptionId, authentication }: IUserSettingsProps) => {
  const { t } = useTranslation('stillingar');
  const { enqueueSnackbar } = useSnackbar();

  const { accountInput } = authentication;
  const client = useApolloClient();

  const [newInputData, setNewInputData] = useState<IProfile | null>(null);

  const [isLoading, setIsLoading] = useState(false);
  const [profile, setProfile] = useState<IProfile>();
  const [isValidSSN, setIsValidSSN] = useState(true);
  const [updateSubscription] = useMutation(UPDATE_SUBSCRIPTION);

  const { loading, error, data, refetch } = useQuery<IUserData>(SUBSCRIPTIONUSER, {
    variables: { subscriptionId, accountInput, servicesRequired: false },
  });

  useEffect(() => {
    if (data?.me?.profiles[0]) {
      setProfile(data?.me?.profiles[0]);
      setNewInputData(data?.me?.profiles[0]);
    }
  }, [data]);

  const setNewValue = (
    newValue: string | boolean,
    key: 'name' | 'ssn' | 'email' | 'allowMarketing' | 'isVisibleInPhonebook' | 'phoneNumber',
  ) => {
    setNewInputData({
      ...(newInputData as IProfile),
      [key]: newValue,
    });
  };

  if (loading || error || !data?.me?.profiles[0] || !profile || !newInputData) {
    return <div>Loading...</div>;
  }

  const isFiber = data?.me?.profiles[0]?.rateplan?.typeId === 'fiber';

  const submitChanges = async () => {
    const { ssn, email, allowMarketing, isVisibleInPhonebook, phoneNumber } = newInputData;
    setIsLoading(true);

    try {
      const ssnChange = profile.ssn !== ssn;

      const payload = {
        contactSsn: ssnChange ? ssn : null,
        email: profile.email !== email || ssnChange ? email : null,
        allowMarketing: profile.allowMarketing !== allowMarketing ? allowMarketing : null,
        isVisibleInPhonebook:
          profile.isVisibleInPhonebook !== isVisibleInPhonebook ? isVisibleInPhonebook : null,
        phoneNumber:
          profile.phoneNumber !== phoneNumber || (ssnChange && isFiber) ? phoneNumber : null,
      };
      const { data } = await updateSubscription({
        variables: {
          input: payload,
          subscriptionId,
          phoneNumber: null,
        },
      });

      await refetch();

      const {
        updateSubscription: { error },
      } = data;
      setIsLoading(false);
      if (error) {
        enqueueSnackbar(`${t('user.error')}: ${error.message}`, {
          variant: 'error',
        });
        return;
      }

      if (error) {
        enqueueSnackbar(t('user.generalUpdateError'), {
          variant: 'error',
        });
        return;
      }

      setProfile({
        ...profile,
      });
      enqueueSnackbar(t('user.successfullyUpdated'), {
        variant: 'success',
      });
    } catch (e) {
      setIsLoading(false);
      enqueueSnackbar(`${t('user.error')}: ${e.message}`, {
        variant: 'error',
      });
    }
  };

  const onChangeSsn = async (ssn: string) => {
    if (ssn.length === 10) {
      try {
        const { data } = await client.query({
          query: KENNITALA,
          variables: { ssn },
        });
        setIsValidSSN(true);

        const {
          kennitala: { name },
        } = data;

        setNewInputData({
          ...newInputData,
          name,
          ssn,
        });
      } catch (e) {
        setIsValidSSN(false);
        enqueueSnackbar(t('user.generalUpdateError'), {
          variant: 'error',
        });
      }
    } else {
      setIsValidSSN(false);
    }
  };
  return (
    <Box padding={4} marginX={{ sm: 0, md: 5 }} marginBottom={4}>
      <Grid gridTemplate={{ sm: 1, md: 2 }} rowGap={4} columnGap={4}>
        <GridItem>
          <Input
            id="kennitala"
            name="kennitala"
            type="number"
            autoComplete="on"
            defaultValue={newInputData?.ssn}
            onChange={(e) => onChangeSsn(e.target.value)}
            label={t('user.ssn')}
            disabled
            color={color}
          />
        </GridItem>
        <GridItem>
          <Input
            id="name"
            name="name"
            type="text"
            autoComplete="on"
            defaultValue={newInputData?.name}
            value={newInputData?.name}
            onChange={(e) => setNewValue(e.target.value, 'name')}
            label={t('user.name')}
            disabled
            color={color}
          />
        </GridItem>
        <GridItem>
          <Input
            id="email"
            name="Netfang"
            type="email"
            autoComplete="on"
            defaultValue={newInputData?.email}
            onChange={(e) => setNewValue(e.target.value, 'email')}
            label={t('user.email')}
            color={color}
          />
        </GridItem>
        <GridItem>
          {isFiber && (
            <Input
              id="phonenumber"
              name="phoneNumber"
              type="number"
              autoComplete="on"
              defaultValue={newInputData.phoneNumber}
              onChange={(e) => setNewValue(e.target.value, 'phoneNumber')}
              label={t('user.fiberInfo.contact')}
              color={color}
            />
          )}
        </GridItem>
        <GridItem>
          <Box marginBottom={1}>
            <Checkbox
              type="checked"
              value={t('user.information.isVisibleInPhonebook.title')}
              isChecked={newInputData?.isVisibleInPhonebook || false}
              onChange={() =>
                setNewValue(!newInputData?.isVisibleInPhonebook, 'isVisibleInPhonebook')
              }
              color={color}
            />
          </Box>
          <Text color="black100" variant="pSmallRegular">
            {t('user.information.isVisibleInPhonebook.description')}
          </Text>
        </GridItem>
        <GridItem>
          <Box marginBottom={1}>
            <Checkbox
              type="checked"
              value={t('user.information.allowMarketing.title')}
              isChecked={newInputData?.allowMarketing || false}
              onChange={() => setNewValue(!newInputData?.allowMarketing, 'allowMarketing')}
              color={color}
            />
          </Box>
          <Text color="black100" variant="pSmallRegular">
            {t('user.information.allowMarketing.description')}
          </Text>
        </GridItem>
        <GridItem>
          <MainButton
            text={t('plan.button')}
            colorScheme={color}
            icon="longArrowRight"
            onClick={() => submitChanges()}
            isLoading={isLoading || loading}
            isDisabled={profile === newInputData || !isValidSSN}
          />
        </GridItem>
      </Grid>
    </Box>
  );
};
export default inject('authentication', 'profiles')(UserSettings);
