import * as React from 'react';
import { useMutation, useQuery } from '@apollo/client';
import {
  Box,
  Button,
  CheckboxDeprecated,
  ErrorMessage,
  FormDropdown,
  Grid,
  GridItem,
  LoadingPlaceholder,
  MainButton,
  PaymentSection,
  SecondaryButton,
  Text,
} from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import LinkWrapper from 'components/link-wrapper/LinkWrapper';
import { CHANGE_SUBSCRIPTION_RATEPLAN } from 'graphql/mutations/rateplan';
import { CARDS } from 'graphql/queries/cards';
import { ALLRATEPLANS } from 'graphql/queries/rateplans';
import { inject } from 'mobx-react';
import { useSnackbar } from 'notistack';
import { IProfile, IRateplanCategory, IUserData } from 'typings';
import { formatPrice, profileColor } from 'utils/helpers';
import { useTranslation } from 'utils/i18n';

import { SUBSCRIPTION_PLAN } from '../../../thjonustuleid/queries/thjonustuleid';

interface IProps {
  subscription: IProfile;
  color: string;
  authentication?: any;
}
interface ITjonustuleidProps {
  subscriptionId: string;
  authentication?: any;
}
interface IPlanProps extends IProps {
  change?: any;
  allowedToChange: boolean;
}

interface IPaymentsProps {
  onSelectCard: any;
  onSelectPaymentType: any;
  selectedPaymentType: string;
  authentication?: any;
  color: string;
}

const Plan = ({ subscription, color, allowedToChange, authentication }: IPlanProps) => {
  const { accountInput, isStaff } = authentication;
  const { rateplan, subscriptionId } = subscription;
  const [changeSubscriptionRateplan] = useMutation(CHANGE_SUBSCRIPTION_RATEPLAN);
  const { loading, error, data } = useQuery<IRateplanCategory>(ALLRATEPLANS);
  const { enqueueSnackbar } = useSnackbar();
  const { t } = useTranslation('stillingar');

  const [selectedRateplanId, setCurrRateplan] = React.useState('');
  const [selectedServicepackId, setCurrServicepack] = React.useState('');
  const [card, setCard] = React.useState('');
  const [paymentType, setPaymentType] = React.useState('card');
  const [message, setMessage] = React.useState('');
  const [loadingButton, setLoading] = React.useState(false);
  const [activateNextMonth, setActivateNextMonth] = React.useState(false);

  const onSubmit = async (e: React.MouseEvent) => {
    e.preventDefault();
    setMessage('');

    if (!selectedRateplanId) {
      setMessage(t('plan.errorMessage'));
      return;
    }

    try {
      setLoading(true);

      const res = await changeSubscriptionRateplan({
        variables: {
          subscriptionId,
          input: {
            rateplanId: selectedRateplanId,
            paymentId: paymentType === 'card' ? card : null,
            servicepackId: selectedServicepackId,
            paymentType,
            activateNextMonth,
          },
        },
        refetchQueries: [{ query: SUBSCRIPTION_PLAN, variables: { subscriptionId, accountInput } }],
        awaitRefetchQueries: true,
      });

      setLoading(false);

      if (res.data.changeSubscriptionRateplan.error) {
        throw new Error(res.data.changeSubscriptionRateplan.error.message as string);
      } else {
        enqueueSnackbar(t('plan.successMessage'), {
          variant: 'success',
        });
        setCurrServicepack('');
        setCurrRateplan('');
        setCard('');
        setPaymentType('card');
        setActivateNextMonth(false);
      }
    } catch (e: any) {
      enqueueSnackbar(t('plan.error', { error: e.message }), {
        variant: 'error',
      });
      setMessage(e?.message as string);
      setLoading(false);
    }
  };

  if (loading || error || !data) {
    return <div>{'Sæki...'}</div>;
  }

  const category = rateplan.availableRateplans[0];
  const dislplayRateplans = isStaff
    ? category?.rateplans
    : category?.rateplans.filter((r) => !r.isVip);

  const rateplans = data?.rateplans;
  const selectedRateplan = rateplans?.find((r) => r.id === selectedRateplanId);
  const servicepacks =
    selectedRateplan?.id === 'R2088' &&
    selectedRateplan?.availableServicepacks.find((s) => s.servicepackType === 'phonedata');

  // payment required if rateplan change from prepaid -> postpaid else if postpaid -> postpaid existing payment method is used
  const needsPayment = rateplan.isPrepaid && selectedRateplan && !selectedRateplan.isPrepaid;

  const disabled =
    !selectedRateplanId ||
    (needsPayment && !card && paymentType !== 'bank') ||
    (servicepacks && !selectedServicepackId);

  const onSelect = (rateplanId: string) => {
    setCurrRateplan(rateplanId);
    setCurrServicepack('');
  };

  return (
    <>
      <Text variant="pMediumRegular">
        {t('plan.current')} <strong>{rateplan.title}</strong>
      </Text>

      {/* TODO: move text to contentful */}
      {rateplan.id === 'R1150' && <div>{t('plan.descriptionHraðleið')}</div>}

      {dislplayRateplans && allowedToChange && (
        <>
          {message && <ErrorMessage>{message}</ErrorMessage>}
          <Grid gridTemplate={{ sm: 1, md: 12 }} rowGap={4} columnGap={4}>
            <GridItem gridColumn={{ sm: 'span12' }}>
              <FormDropdown onSelect={onSelect} label={t('plan.choosePlan')}>
                {dislplayRateplans.map(({ price, id, title }) => (
                  <option key={id} value={id}>
                    {title} - {formatPrice(price)}
                  </option>
                ))}
              </FormDropdown>
            </GridItem>
            {servicepacks && (
              <GridItem gridColumn={{ sm: 'span12' }}>
                <FormDropdown
                  onSelect={(servicepackId: string) => setCurrServicepack(servicepackId)}
                  label={t('plan.chooseData')}
                >
                  {servicepacks?.servicepacks
                    .filter((s) => s.forSale)
                    .map(({ title, price, id }) => (
                      <option key={id} value={id}>
                        {title} - {formatPrice(price)}
                      </option>
                    ))}
                </FormDropdown>
              </GridItem>
            )}

            {needsPayment && (
              <GridItem gridColumn={{ sm: 'span12' }}>
                <Payments
                  onSelectCard={(cardId: string) => setCard(cardId)}
                  onSelectPaymentType={(e: { target: { checked: boolean } }) =>
                    setPaymentType(e.target.checked ? 'bank' : 'card')
                  }
                  selectedPaymentType={paymentType}
                  authentication={authentication}
                  color={color}
                />
              </GridItem>
            )}

            <GridItem gridColumn={{ sm: 'span12', md: 'span6' }}>
              <Box display="flex" flexDirection="column">
                <Box marginBottom={2}>
                  <CheckboxDeprecated
                    color={color}
                    name="activateNextMonth"
                    checked={activateNextMonth}
                    onChange={(e: { target: { checked: boolean } }) =>
                      setActivateNextMonth(e.target.checked)
                    }
                  >
                    {t('plan.activateNextMonth')}
                  </CheckboxDeprecated>
                </Box>
                <MainButton
                  text={t('plan.button')}
                  isLoading={loadingButton}
                  onClick={(e) => {
                    if (e) {
                      onSubmit(e);
                    }
                  }}
                  isDisabled={disabled}
                  colorScheme={color as MainColorType}
                  icon="longArrowRight"
                />
              </Box>
            </GridItem>
          </Grid>
        </>
        //</form>
      )}
    </>
  );
};

const Cancel = ({ subscription, color, authentication }: IProps) => {
  const { subscriptionId, title } = subscription;
  const { accountInput } = authentication;
  const { t } = useTranslation('stillingar');

  return (
    <Button
      linkComponent={
        <LinkWrapper href={`/${accountInput.ssn}/thjonusta/${subscriptionId}/uppsogn`} />
      }
      outline={color}
      background="white"
      text={color}
    >
      {t('plan.cancelService', { subscriptionTitle: title })}
    </Button>
  );
};

const Payments = ({
  onSelectCard,
  onSelectPaymentType,
  authentication,
  color,
  selectedPaymentType,
}: IPaymentsProps) => {
  const { accountInput, isStaff } = authentication;
  const { loading, error, data } = useQuery<IUserData>(CARDS, { variables: { accountInput } });
  const { t } = useTranslation('stillingar');

  if (loading || error || !data) {
    return <div>{t('plan.payments.loading')}</div>;
  }
  const cards = data?.me?.cards;

  const subtitle = (
    <>
      <Box marginBottom={2}>
        <Text variant="pMediumRegular">{t('plan.payments.subtitle')}</Text>
      </Box>
      <Box display="flex" justifyContent="flex-end">
        <SecondaryButton
          icon={'add'}
          href={`/stillingar/payment${isStaff && `?ssn=${accountInput.ssn}`}`}
          text={t('plan.payments.linkTitle')}
          renderAs="a"
          colorScheme={color as MainColorType}
        />
      </Box>
    </>
  );

  return (
    <>
      <Text variant="subtitleBold">{t('plan.payments.title')}</Text>
      <Text variant="pMediumRegular">{subtitle}</Text>
      {selectedPaymentType !== 'bank' && cards?.length > 0 && (
        <FormDropdown onSelect={onSelectCard} label={t('plan.payments.chooseCard')}>
          {cards?.map(({ id, maskedNumber, issuer }) => (
            <option key={id} value={id}>
              {issuer} - {maskedNumber.substring(maskedNumber.length - 8, maskedNumber.length)}
            </option>
          ))}
        </FormDropdown>
      )}
      <CheckboxDeprecated
        color={color}
        name="allowMarketing"
        checked={selectedPaymentType === 'bank'}
        onChange={onSelectPaymentType}
      >
        {t('plan.payments.bank')}
      </CheckboxDeprecated>
    </>
  );
};

const Thjonustuleid = ({ subscriptionId, authentication }: ITjonustuleidProps) => {
  const { accountInput, isStaff } = authentication;
  const { loading, error, data } = useQuery<IUserData>(SUBSCRIPTION_PLAN, {
    variables: { subscriptionId, accountInput },
  });
  const { t } = useTranslation('stillingar');

  const subscription = data?.me.subscriptions.subscriptions[0];
  const color = subscription?.rateplan && profileColor(subscription?.rateplan);
  const allowedToChange = isStaff || subscription?.isPayer;

  const subscriptionTitle = subscription?.title;

  if (!subscription) {
    return null;
  }

  return (
    <Box padding={4} marginX={{ sm: 0, md: 5 }} marginBottom={4}>
      <Box>
        {loading || error ? (
          <>
            <Box marginBottom={2}>
              <LoadingPlaceholder height={2} width="5/12" />
            </Box>
            <Box>
              <LoadingPlaceholder height={6} width="10/12" />
            </Box>
          </>
        ) : (
          <Plan
            subscription={subscription}
            color={color as MainColorType}
            authentication={authentication}
            allowedToChange={allowedToChange}
          />
        )}
      </Box>
      {(subscription?.rateplan?.typeId === 'service_bundle' ||
        subscription?.rateplan?.typeId === 'vip_service_bundle') && (
        <PaymentSection
          smallerTitle
          fullWidth
          noSpacingTop
          title={t('plan.cancelService', { subscriptionTitle })}
          subtitle={t(`plan.cancelServiceDescription${subscriptionTitle}`)}
        >
          {loading || error ? (
            <div>...</div>
          ) : (
            <Cancel
              subscription={subscription}
              color={color as MainColorType}
              authentication={authentication}
            />
          )}
        </PaymentSection>
      )}
    </Box>
  );
};

Thjonustuleid.getInitialProps = ({ query }: any) => {
  return {
    subscriptionId: query.subscriptionId,
    namespacesRequired: ['stillingar'],
  };
};

export default inject('authentication')(Thjonustuleid);
