import React from 'react';
import { Controller, useForm } from 'react-hook-form';
import { ErrorMessage } from '@hookform/error-message';
import {
  Box,
  FormStatusMessage,
  Grid,
  GridItem,
  MainButton,
  NumberInput,
  Select,
  SingleSelect,
  Text,
} from '@nova-hf/ui';
import { IContext } from 'beta/typings/context';
import Step from 'containers/checkout';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';
import Authentication from 'store/authentication';
import {
  MobileConsolationInput,
  MobileConsolationType,
  useMobileConsolationMutation,
  useSubscriptionQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

type SarabaeturProps = {
  subscriptionId: string;
  ssn: string;
  authentication: Authentication;
};

const Sarabaetur = ({ authentication, subscriptionId, ssn }: SarabaeturProps) => {
  const router = useRouter();
  const { t } = useTranslation('service');
  const accountInput = authentication.accountInput;
  const { enqueueSnackbar } = useSnackbar();
  const { data: subData, loading: subLoading } = useSubscriptionQuery({
    variables: {
      subscriptionId,
      accountInput,
    },
    skip: !subscriptionId || !accountInput.ssn,
  });
  const profile = subData?.me?.profiles?.[0];
  const rateplan = profile?.rateplan;
  const isFrelsi = rateplan?.title?.toLowerCase().includes('frelsi');
  const isOskrad =
    !router.query.ssn || router.query.ssn === 'undefined' || router.query.ssn === '9999999999'; // i do this because the query param is string and therefore undefined does not match the first condition
  const COLOR = isFrelsi ? 'pink' : 'ocean';
  const reasons = [
    'Netþjónusta',
    'Netið í símann',
    'Endurreiknaðir reikningar',
    'Sárabætur, mistök hjá Nova',
    'Gjöf / Glaðningur til viðskiptavinar',
    'Samningar / Markaðsstarf',
    'Startpakki',
    'Sjálfvirk áfylling',
    'Útlandanotkun',
    'Annað',
  ];
  const types = ['Gagnamagn(GB)', 'Krónur'];
  const [consolation, { loading: consolationLoading, error: consolationError }] =
    useMobileConsolationMutation({
      onCompleted(data) {
        if (data?.mobileConsolation?.message) {
          enqueueSnackbar(t('consolations.success'), {
            variant: 'success',
          });
          router.push(`/${ssn}/thjonusta/${subscriptionId}`);
        }
      },
      onError(error) {
        if (error) {
          enqueueSnackbar(t('consolations.fail'), {
            variant: 'error',
          });
        }
      },
    });

  const {
    control,
    handleSubmit,
    setValue,
    formState: { isValid },
    trigger,
    watch,
  } = useForm<MobileConsolationInput>({
    defaultValues: {
      amount: undefined,
      reason: '',
      type: MobileConsolationType.Data,
    },
    delayError: 500,
    mode: 'onChange',
  });

  const { reason, amount, type } = watch();

  const onSubmit = () => {
    if (reason && amount && type) {
      consolation({
        variables: {
          input: {
            phoneNumber: subscriptionId,
            reason: reason,
            amount: amount,
            type: type,
          },
        },
      });
    }
  };

  return (
    <Step
      color={COLOR}
      titleSteps={['Sárabætur']}
      returnLink={subscriptionId && `/${ssn}/thjonusta/${subscriptionId}`}
      checkoutLink="sarabaetur"
      totalSteps={1}
      subscriptionId={subscriptionId}
      doNotUseStepChange={true}
    >
      <Box renderAs="form" onSubmit={handleSubmit(onSubmit)}>
        <Grid gridTemplate={{ sm: 4 }}>
          <GridItem gridColumn={{ sm: 'span4' }}>
            <Box display="flex" flexDirection="column" gap={3}>
              <Text color="black100" variant="h6">
                Sárabætur
              </Text>
              <Text
                color="black100"
                variant="subHeading"
              >{`Hér getur þú græjað sárabætur fyrir símanúmer ${subscriptionId}`}</Text>
              <Text color="black100" variant="pMediumRegular">
                {t('consolations.infoOne')}
              </Text>
              <Text color="black100" variant="pMediumRegular">
                {t('consolations.infoTwo')}
              </Text>
              <Text color="black100" variant="pMediumRegular">
                {t('consolations.infoThree')}
              </Text>
            </Box>
          </GridItem>
          <GridItem gridColumn={{ sm: 'span4' }}>
            <Controller
              name="reason"
              control={control}
              rules={{
                required: t('consolations.reasonError').toString(),
              }}
              render={({ field, formState: { errors } }) => {
                const { name, onChange } = field;
                return (
                  <Box>
                    <SingleSelect
                      color={COLOR}
                      defaultMenuIsOpen={false}
                      placeholder={t('adjustments.chooseReason')}
                      id="reason"
                      label={t('adjustments.chooseReason')}
                      maxMenuHeight={250}
                      onChange={(e) => {
                        onChange(e?.value);
                      }}
                      isClearable={false}
                      options={reasons.map((reason) => ({
                        label: reason,
                        value: reason,
                      }))}
                      required
                      isDisabled={consolationLoading}
                    />
                    <ErrorMessage
                      errors={errors}
                      name={name}
                      render={({ message }) => (
                        <FormStatusMessage message={message} status="error" />
                      )}
                    />
                  </Box>
                );
              }}
            />
          </GridItem>
          {(isFrelsi || isOskrad) && (
            <GridItem gridColumn={{ sm: 'span4' }}>
              <Controller
                name="type"
                control={control}
                rules={{
                  required: isFrelsi || isOskrad,
                }}
                render={({ field, formState: { errors } }) => {
                  const { name } = field;
                  return (
                    <Box>
                      <Select
                        id="type"
                        label={t('consolations.type')}
                        name={name}
                        isBold={false}
                        onChange={(e) => {
                          const selectedType = e.target.value;
                          setValue('type', selectedType as MobileConsolationType);
                        }}
                        disabled={subLoading}
                        required={isFrelsi || isOskrad}
                      >
                        <option value="" hidden>
                          {t('consolations.select')}
                        </option>
                        {types?.map((type, index) => {
                          return (
                            <option
                              key={index}
                              value={
                                type === 'Gagnamagn(GB)'
                                  ? MobileConsolationType.Data
                                  : MobileConsolationType.MoneyTopup
                              }
                            >
                              {type}
                            </option>
                          );
                        })}
                      </Select>
                      <ErrorMessage
                        errors={errors}
                        name={name}
                        render={() => (
                          <FormStatusMessage message={t('consolations.typeError')} status="error" />
                        )}
                      />
                    </Box>
                  );
                }}
              />
            </GridItem>
          )}
          <GridItem gridColumn={{ sm: 'span4' }}>
            <Controller
              name="amount"
              rules={{
                required: t('adjustments.amountMissing').toString(),
                validate: {
                  min: (value) =>
                    Number(value) > 0 ? true : t('consolations.amountError').toString(),
                  max: (value) =>
                    (type === MobileConsolationType.Data && Number(value) <= 250) ||
                    (type === MobileConsolationType.MoneyTopup && Number(value) <= 9000)
                      ? true
                      : t('consolations.amountError').toString(),
                },
              }}
              control={control}
              render={({ field, formState: { errors } }) => {
                const { name } = field;
                return (
                  <Box>
                    <NumberInput
                      id="amount"
                      numberType="number"
                      label={isFrelsi || isOskrad ? t('adjustments.amount') : 'Upphæð(GB)'}
                      required
                      name={name}
                      value={field?.value?.toString() ?? ''}
                      onChange={(value) => {
                        if (!value) {
                          setValue('amount', undefined);
                        } else {
                          setValue('amount', Number(value));
                        }
                        trigger('amount');
                      }}
                      onBlur={field.onBlur}
                    />
                    <ErrorMessage
                      errors={errors}
                      name={name}
                      render={({ message }) => (
                        <FormStatusMessage message={message} status="error" />
                      )}
                    />
                  </Box>
                );
              }}
            />
          </GridItem>
          {consolationError && (
            <GridItem gridColumn={{ sm: 'span4' }}>
              <FormStatusMessage message={t('adjustments.error')} status="error" />
            </GridItem>
          )}
          <GridItem gridColumn={{ sm: 'span4' }}>
            <Box
              display="flex"
              marginTop={6}
              marginBottom={10}
              justifyContent="flex-end"
              flexDirection={{ sm: 'column', md: 'row' }}
            >
              <Box display="flex" width={{ sm: '100%', md: '4/12' }}>
                <MainButton
                  text={t('consolations.buttonText')}
                  colorScheme={COLOR}
                  isSubmitButton
                  isLoading={consolationLoading}
                  isDisabled={!isValid}
                />
              </Box>
            </Box>
          </GridItem>
        </Grid>
      </Box>
    </Step>
  );
};

Sarabaetur.getInitialProps = ({ pathname, query }: IContext) => {
  return {
    pathname,
    ssn: query.ssn,
    subscriptionId: query.subscriptionId,
    namespacesRequired: ['service'],
  };
};

export default inject('authentication')(observer(Sarabaetur));
