import React, { useEffect, useState } from 'react';
import { Box, Checkbox, Icon, IconButton, LoadingPage, Text, useViewport } from '@nova-hf/ui';
import SVGMasterCard from 'assets/svg/Mastercard.svg';
import SVGVisa from 'assets/svg/Visa.svg';
import {
  BaseWrapper,
  Button,
  Drawer,
  InputMessage,
  InputWrapper,
  MultipleSelectInOne,
  Select,
  TextInput,
} from 'frisco';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';
import Authentication from 'store/authentication';
import Cart from 'store/cart';
import MobileSignup, { throwErrorWithMessage } from 'store/mobileSignup';
import UI from 'store/ui';
import { IContext } from 'typings/context';
import {
  InputMaybe,
  PaymentInfoInput,
  PaymentType,
  ShippingType,
  useAddCardMutation,
  useAddPaymentToOrderMutation,
  useCardsQuery,
  useCreateOrderMutation,
  useMobileCartQuery,
} from 'typings/graphql';

import LayoutWrapper from '../components/LayoutWrapper';
import PortInDate from '../components/PortInDate';

import CardForm from './components/cardForm';

type GreidslaProps = {
  mobileSignup: MobileSignup;
  cart: Cart;
  authentication?: Authentication;
  ui: UI;
};

type PaymentMethodForm = {
  expiry: string;
  cvc: string;
  cardNumber: string;
};

const Greidsla = ({ mobileSignup, cart, authentication, ui }: GreidslaProps) => {
  const router = useRouter();
  const { isSmall } = useViewport();
  const isMobile = isSmall;
  const [phoneNumber, setPhoneNumber] = useState<string>('');
  const [email, setEmail] = useState<string>('');
  const phoneNumberHasError =
    (phoneNumber?.length > 0 && phoneNumber?.length < 7) || phoneNumber?.length > 7;
  const emailHasError = !!email && !(email?.includes('@') || email?.includes('.'));
  const [selectedPaymentMethod, setSelectedPaymentMethod] = useState('');
  const [hasAcceptedTerms, setHasAcceptedTerms] = useState(false);
  const [drawer, setDrawer] = useState(false);
  const { enqueueSnackbar } = useSnackbar();
  const {
    data: cartData,
    refetch: cartRefetch,
    loading: cartLoading,
  } = useMobileCartQuery({
    variables: { input: { cartId: cart.activeCartId } },
    initialFetchPolicy: 'no-cache',
  });
  ui?.setIsHiddenFooter(true);
  const contact = cartData?.cart?.contact;

  const availableRecurringPaymentMethods =
    cartData?.cart?.paymentRequirements?.availableRecurringPaymentMethods;
  const requiresRecurringPaymentInfo =
    cartData?.cart?.paymentRequirements?.requiresRecurringPaymentInfo;
  const requiresPaymentInfo = cartData?.cart?.paymentRequirements?.requiresPaymentInfo;

  const displayBankForStaff =
    availableRecurringPaymentMethods?.includes(PaymentType.Bank) && authentication?.staffInStore;
  const displayBank =
    cartData?.cart?.totalDue === 0 && availableRecurringPaymentMethods?.includes(PaymentType.Bank);

  const [createOrder, { loading: orderLoading, error: orderError }] = useCreateOrderMutation();
  const [addPayment, { loading: paymentLoading, error: paymentError }] =
    useAddPaymentToOrderMutation();
  const [otherErrorWorthDisplaying, setOtherErrorWorthDisplaying] = useState('');

  const getCardIcon = (issuer: string) => {
    switch (issuer.toLowerCase()) {
      case 'visa':
        return <SVGVisa />;
      case 'mastercard':
        return <SVGMasterCard />;
      case 'maestro':
        return <SVGMasterCard />;
      default:
        return 'creditcard';
    }
  };

  const addContactToCart = () => {
    const user = cartData?.cart?.contact;
    const updatedUser = {
      email: email.length ? email : '',
      msisdn: phoneNumber.length ? phoneNumber : '',
      ssn: user?.ssn ?? '',
      id: user?.id ?? '',
      name: user?.name ?? '',
      address: user?.address ?? '',
      zip: user?.zip ?? '',
    };
    mobileSignup?.addContactToCart(updatedUser);
    cartRefetch();
  };

  const { data: paymentMethodsData, refetch: paymentMethodsRefetch } = useCardsQuery({
    variables: {
      accountInput: {
        ssn: contact?.ssn ?? '',
      },
    },
    skip: !contact?.ssn,
  });

  useEffect(() => {
    if (cartData?.cart?.contact) {
      setPhoneNumber(cartData?.cart?.contact?.msisdn ?? '');
      setEmail(cartData?.cart?.contact?.email ?? '');
      paymentMethodsRefetch();
    }
  }, [cartData?.cart?.contact]);

  const [addPaymentMethod] = useAddCardMutation({
    onCompleted: (data) => {
      if (data?.addCard?.card?.id) {
        setSelectedPaymentMethod(data?.addCard?.card?.id);
        enqueueSnackbar('Tókst að bæta við korti', {
          variant: 'success',
        });
        paymentMethodsRefetch();
      }
    },
    onError: (error) => {
      if (error)
        enqueueSnackbar('Ekki tókst að bæta við korti', {
          variant: 'error',
        });
    },
  });

  const cards = paymentMethodsData?.me?.cards;
  const isNewNumber = mobileSignup?.servicePurchaseInfo.service?.isNewNumber;

  const onSubmitNew = async (form: PaymentMethodForm) => {
    await addPaymentMethod({
      variables: {
        input: {
          cardNumber: form?.cardNumber,
          ssn: contact?.ssn ?? '',
          cvc: form?.cvc,
          expiryMonth: form?.expiry.substring(0, 2),
          expiryYear: form?.expiry.substring(2, 4),
        },
      },
    });
  };

  const addShippingMethodToCart = async () => {
    try {
      await cart.addShippingMethod();
    } catch (e) {
      throwErrorWithMessage(e, 'failed to add shippingmethod');
    }
  };

  const onPay = async () => {
    if ((email && email !== contact?.email) || (phoneNumber && phoneNumber !== contact?.msisdn)) {
      addContactToCart();
    }
    const hasPlastic = await mobileSignup.hasPlasticSimCard();
    if (hasPlastic && !authentication?.staffInStore) {
      await addShippingMethodToCart();
    } else {
      // If there is no plastic sim card then we only have esim.
      // If staff is in retail we want to ship those esims infos to retail
      // to staff location where they're registered.
      if (authentication?.staffInStore) {
        cart.setShippingMethods({
          shippingType: ShippingType.InStore,
          shippingDetails: {
            storename: authentication?.staffSalesLocation?.salesLocation,
          },
        });
        await addShippingMethodToCart();
      }
    }

    if (cart.activeCartId) {
      const res = await createOrder({
        variables: {
          input: {
            cartId: cart.activeCartId,
          },
        },
      });
      const orderId = res.data?.createOrder.order?.id;
      if (!orderId) {
        setOtherErrorWorthDisplaying('Ekki tókst að stofna pöntun.');
      }
      if (orderId && selectedPaymentMethod === 'bank') {
        let paymentInfo: InputMaybe<PaymentInfoInput> = {
          payerSsn: contact?.ssn ?? '',
          amount: cartData?.cart?.totalDue ?? 0,
          paymentType: PaymentType.Bank,
        };

        if (authentication?.isStaff && cart.shipmentOptions.shippingType === ShippingType.InStore) {
          paymentInfo = {
            paymentType: PaymentType.Pos,
            terminalId: cart?.shipmentOptions?.shippingDetails?.storename,
            payerSsn: cartData?.cart?.contact?.ssn,
            amount: cartData?.cart?.totalDue ?? 0,
          };
        }
        const res = await addPayment({
          variables: {
            input: {
              orderId: orderId,
              ...(requiresPaymentInfo && {
                paymentInfo,
              }),
              ...(requiresRecurringPaymentInfo && {
                recurringPaymentInfo: {
                  amount: cartData?.cart?.totalSubscriptionFee ?? 0,
                  paymentType: PaymentType.Bank,
                  payerSsn: contact?.ssn ?? '',
                },
              }),
            },
          },
        });
        if (res?.data?.addPaymentToOrder?.order?.id) {
          router?.push(`/farsimi/takk/${res?.data?.addPaymentToOrder?.order?.id}`);
        }
      }
      if (orderId && selectedPaymentMethod.length > 0 && selectedPaymentMethod !== 'bank') {
        let paymentInfo: InputMaybe<PaymentInfoInput> = {
          savedPaymentMethodId: selectedPaymentMethod,
          amount: cartData?.cart?.totalDue ?? 0,
          paymentType: PaymentType.SavedPayment,
          payerSsn: cartData?.cart?.contact?.ssn,
        };

        if (authentication?.isStaff && cart.shipmentOptions.shippingType === ShippingType.InStore) {
          paymentInfo = {
            paymentType: PaymentType.Pos,
            terminalId: cart?.shipmentOptions?.shippingDetails?.storename,
            payerSsn: cartData?.cart?.contact?.ssn,
            amount: cartData?.cart?.totalDue ?? 0,
          };
        }

        const res = await addPayment({
          variables: {
            input: {
              orderId: orderId,
              ...(requiresPaymentInfo && {
                paymentInfo,
              }),
              ...(requiresRecurringPaymentInfo && {
                recurringPaymentInfo: {
                  amount: cartData?.cart?.totalSubscriptionFee ?? 0,
                  paymentType: PaymentType.SavedPayment,
                  savedPaymentMethodId: selectedPaymentMethod,
                  payerSsn: cartData?.cart?.contact?.ssn,
                },
              }),
            },
          },
        });
        if (res?.data?.addPaymentToOrder?.order?.id) {
          cart?.setCustomerId('');
          router?.push(`/farsimi/takk/${res?.data?.addPaymentToOrder?.order?.id}`);
        }
      }
    }
  };

  return (
    <LayoutWrapper
      hideNowAndLater={drawer && isMobile}
      image="https://images.ctfassets.net/j5d5y4z9f7ki/4vxVlMx598Ipg9y63ZRE5Q/38b586f638e0b9fab17c1f7a041a0d6e/22dda7f467b236ec2d7f913be0436f48bf7793d9.jpg"
    >
      {cartLoading ? (
        <Box>
          <LoadingPage title={'Sæki greiðslu upplýsingar'} timeToLoad={5} isLoading={true} />;
        </Box>
      ) : (
        <Box>
          {!isNewNumber && (
            <Box
              className="force-width"
              display="flex"
              width="100%"
              justifyContent="center"
              marginTop={5}
              style={{ minHeight: '100vh' }}
            >
              <PortInDate />
            </Box>
          )}
          <Box
            display="flex"
            flexDirection="column"
            alignItems="center"
            justifyContent="center"
            width="100%"
            style={{ minHeight: '100vh' }}
          >
            <Box marginTop={20} display="flex" flexDirection={'column'} width="100%">
              <Box marginY={2}>
                <Text variant="h5">Greiðandi</Text>
              </Box>
              <BaseWrapper hasBackground>
                <Box marginLeft={1} marginBottom={1} display="flex" flexDirection="column">
                  <Text color="grey500" variant="pXSmallRegular">
                    {`kt. ${contact?.ssn}`}
                  </Text>
                  <Text color="black100" variant="pXSmallBold">
                    {contact?.name}
                  </Text>
                  <Text color="grey500" variant="pXSmallRegular">
                    {`${contact?.address}, ${contact?.zip}`}
                  </Text>
                </Box>
                <Box display="flex" flexDirection="column" gap={1}>
                  <InputWrapper
                    input={
                      <TextInput
                        id="phoneNumber"
                        name="phoneNumber"
                        onChange={(e) => setPhoneNumber(e?.target?.value)}
                        disabled={false}
                        placeholder={'Símanúmer'}
                        value={phoneNumber}
                        autoComplete="tel"
                        required
                        backgroundColor="white"
                      />
                    }
                    slideComponent={<InputMessage status="Error" text={'Símanúmer er ekki gilt'} />}
                    slideActive={phoneNumberHasError}
                  />
                  <InputWrapper
                    input={
                      <TextInput
                        id="email"
                        name="email"
                        onChange={(e) => setEmail(e?.target?.value)}
                        disabled={false}
                        placeholder={'Netfang'}
                        value={email}
                        autoComplete="email"
                        required
                        backgroundColor="white"
                      />
                    }
                    slideComponent={<InputMessage status="Error" text={'Netfang er ekki gilt'} />}
                    slideActive={emailHasError}
                  />
                </Box>
              </BaseWrapper>
              <Box marginY={3} id="payer">
                <Box marginBottom={2}>
                  <Text variant="h5">Veldu greiðsluleið</Text>
                </Box>
                {authentication?.staffInStore && (
                  <Select
                    title="Staðgreiðsla verður send á kassa"
                    isSelected={true}
                    emoji={'heimabanki'}
                  />
                )}
                {displayBankForStaff && (
                  <Select
                    title="Fá mánaðarlegar greiðslur í heimabanka"
                    subtitle="Við sendum reikning á kennitöluna þína. 169 kr. seðilgjald bætist við."
                    isSelected={selectedPaymentMethod === 'bank'}
                    onClick={() => setSelectedPaymentMethod('bank')}
                    emoji={'heimabanki'}
                  />
                )}
                <Box>
                  <MultipleSelectInOne
                    title="Greiðslukort"
                    subtitle="Greiðsla dregst af kortinu mánaðarlega."
                    emoji="kreditkort"
                    selectDudes={[
                      ...(Array.isArray(cards)
                        ? cards
                            .filter((card) => card && card.maskedNumber)
                            .map((card, index) => (
                              <Select
                                key={index}
                                isSelected={selectedPaymentMethod === card.id}
                                onClick={() => setSelectedPaymentMethod(card.id)}
                                icon={card?.issuer ? getCardIcon(card.issuer) : 'creditcard'}
                                title={
                                  card?.maskedNumber
                                    ? card.maskedNumber
                                        .replace(/\s/g, '')
                                        .replace(/\*/g, '∙')
                                        .replace(/(.{4})/g, '$1 ')
                                        .trimEnd()
                                        .replace(/ /g, '   ')
                                    : ''
                                }
                              />
                            ))
                        : []),
                    ]}
                  />
                  <Box>
                    <BaseWrapper hasBackground key="baseWrapper">
                      <Box
                        display="flex"
                        flexDirection="row"
                        alignItems="center"
                        justifyContent="space-between"
                        onClick={() => setDrawer(!drawer)}
                        cursor={{ hover: 'pointer' }}
                      >
                        <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
                          <Icon icon="addCreditcard" color="black100" />
                          <Text variant="pSmallRegular">Bæta við korti</Text>
                        </Box>
                        <IconButton
                          color="black100"
                          hiddenButtonText="Add card"
                          icon={drawer ? 'minus' : 'add'}
                        />
                      </Box>
                      {!isMobile && drawer && (
                        <CardForm
                          buttonText={'Bæta við korti'}
                          isInverted={false}
                          onSubmit={onSubmitNew}
                        />
                      )}
                    </BaseWrapper>
                  </Box>
                </Box>

                {displayBank && !authentication?.staffInStore && (
                  <Select
                    title="Fá mánaðarlegar greiðslur í heimabanka"
                    subtitle="Við sendum reikning á kennitöluna þína. 169 kr. seðilgjald bætist við."
                    isSelected={selectedPaymentMethod === 'bank'}
                    onClick={() => setSelectedPaymentMethod('bank')}
                    emoji={'heimabanki'}
                  />
                )}
              </Box>
            </Box>

            <Box display={'flex'} justifyContent="center" width="100%">
              <Box width="100%">
                <Box
                  display="flex"
                  flexDirection="column"
                  gap={2}
                  marginTop={3}
                  marginBottom={10}
                  width="100%"
                >
                  <Checkbox
                    isChecked={hasAcceptedTerms}
                    type="checked"
                    color="grey500"
                    onChange={() => {
                      setHasAcceptedTerms(!hasAcceptedTerms);
                    }}
                  >
                    <span>
                      Ég samþykki{' '}
                      <a
                        href="https://www.nova.is/baksvids/skilmalar"
                        target="_blank"
                        rel="noopener noreferrer"
                        style={{ color: '#000', textDecoration: 'underline', cursor: 'pointer' }}
                      >
                        skilmála
                      </a>{' '}
                      Nova
                    </span>
                  </Checkbox>
                  {paymentError && (
                    <Text color="warning" variant="pSmallBold">
                      {paymentError?.message}
                    </Text>
                  )}
                  {orderError && (
                    <Text color="warning" variant="pSmallBold">
                      {orderError?.message}
                    </Text>
                  )}
                  {otherErrorWorthDisplaying && (
                    <Text color="warning" variant="pSmallBold">
                      {otherErrorWorthDisplaying}
                    </Text>
                  )}
                  <Button
                    backgroundColor="pink"
                    text="Greiða og byrja með Nova"
                    disabled={
                      !hasAcceptedTerms ||
                      orderLoading ||
                      emailHasError ||
                      phoneNumberHasError ||
                      paymentLoading ||
                      !selectedPaymentMethod
                    }
                    textVariant="pMediumBold"
                    onClick={() => onPay()}
                  />
                </Box>
                {isMobile && (
                  <Drawer
                    onClose={() => {
                      setDrawer(false);
                    }}
                    title="Skrá nýtt kort"
                    isActive={drawer}
                  >
                    <CardForm
                      buttonText={'Bæta við korti'}
                      isInverted={true}
                      onButtonClick={() => setDrawer(false)}
                      onSubmit={onSubmitNew}
                    />
                  </Drawer>
                )}
              </Box>
            </Box>
          </Box>
        </Box>
      )}
    </LayoutWrapper>
  );
};

Greidsla.getInitialProps = ({ pathname }: IContext) => {
  return {
    pathname,
    namespacesRequired: [''],
  };
};

export default inject('mobileSignup', 'cart', 'authentication', 'ui')(observer(Greidsla));
