import React, { useEffect, useState } from 'react';
import {
  Box,
  Grid,
  GridItem,
  Input,
  MainButton,
  makeToast,
  Modal,
  PaymentInfoCard,
  SecondaryButton,
  Tabs,
  Text,
} from '@nova-hf/ui';
import { CardType, PaymentCardProps } from '@nova-hf/ui/umd/ts/src/cards/PaymentCard/PaymentCard';
import { Tab } from '@nova-hf/ui/umd/ts/src/tabs/Tabs';
import AddPaymentCard from 'beta/containers/add-card/AddPaymentCard';
import { PAYMENT_METHODS } from 'beta/graphql/queries/paymentMethods';
import { useRouter } from 'next/router';
import {
  PaymentMethodStatus,
  PaymentTypeV2,
  useCustomerNameQuery,
  useDeletePaymentMethodMutation,
  usePaymentMethodsQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

import { ConfirmDeleteModal } from '../components/ConfirmDeleteModal';
import { StillingarLoader } from '../components/StillingarLoader';

import AddBankClaim from './payments/AddBankClaim';

type CardListItem = {
  id: string;
  title: string;
  card: PaymentCardProps;
}[];

export const Payments = () => {
  const { t } = useTranslation(['stillingar', 'payments']);
  const router = useRouter();
  const customerId: string = (router.query.customerId as string) ?? '';

  const {
    data,
    loading,
    error,
    refetch: paymentRefetch,
  } = usePaymentMethodsQuery({
    variables: {
      input: {
        id: customerId,
        page: 1,
        perPage: 20,
      },
    },
  });

  const { data: customerData } = useCustomerNameQuery({
    variables: { input: { id: customerId } },
  });

  const [receptEmail, setReceptEmail] = useState('');
  const [selectedTab, setSelectedTab] = useState<string>('greidslukort');
  const [paymentMethodId, setPaymentMethodId] = useState('');
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [isDeleteOpen, setIsDeleteOpen] = useState(false);
  const [deletePaymentMethod, { loading: loadingDelete }] = useDeletePaymentMethodMutation({
    refetchQueries: [
      { query: PAYMENT_METHODS, variables: { input: { id: customerId.toString() } } },
    ],
    awaitRefetchQueries: true,
  });
  useEffect(() => {
    paymentRefetch();
  }, []);

  if (error || !data || !customerData?.customer) return null;
  if (loading || loadingDelete) return <StillingarLoader />;

  const getCardList = () => {
    const list: CardListItem = [];
    data.paymentMethods?.paymentmethods?.map((PaymentMethod) => {
      const isCard = PaymentMethod.__typename === 'CreditCardPaymentMethod';
      list.push({
        id: PaymentMethod?.id,
        title: isCard ? 'Kreditkort' : 'Netbanki',
        card: {
          cardType: isCard ? (PaymentMethod?.issuer as CardType) || 'DEFAULT_ISSUER' : 'HEIMABANKI',
          cardNumber: isCard
            ? PaymentMethod?.maskedNumber?.slice(-8) || ''
            : PaymentMethod?.type === PaymentTypeV2.BankClaim
            ? customerData.customer?.name?.split(' ')[0] || ''
            : '',
          expiryDate: isCard
            ? (PaymentMethod?.expiry as string)
            : t('payment.paymentMethod.bankclaim'),
          boxShadow: 'normal',
          hasBorder: false,
          renderAs: 'div',
        },
      });
    });
    return list;
  };

  const onDelete = async (id: string) => {
    try {
      const res = await deletePaymentMethod({
        variables: {
          input: {
            Id: id,
          },
        },
      });
      if (!res.data?.deletePaymentMethod?.message) {
        makeToast.danger(t('payment.paymentMethod.deletePaymentMethodFail'), '');
      } else {
        makeToast.success(t('payment.paymentMethod.deletePaymentMethodSuccess'), '');
      }
    } catch (error) {
      if (error instanceof Error)
        makeToast.danger(t('payment.paymentMethod.deletePaymentMethodFail'), error.message);
    }
    await paymentRefetch();
    setIsDeleteOpen(false);
  };

  const onToBeDeleted = (id: string) => {
    setIsDeleteOpen(true);
    setPaymentMethodId(id);
  };

  const onAddCard = async () => {
    setIsModalOpen(false);
    await paymentRefetch();
  };

  const hasBankClaim = data.paymentMethods?.paymentmethods.filter(
    (payment) =>
      payment.status === PaymentMethodStatus.Active && payment.type === PaymentTypeV2.BankClaim,
  );

  const tabs = (): Tab[] => {
    const tabArray: Tab[] = [
      {
        label: t('payments:card.tabTitle'),
        id: 'greidslukort',
        onClick: () => setSelectedTab('greidslukort'),
        panelContent: (
          <Box paddingY={5}>
            <AddPaymentCard
              customerId={customerId}
              onConfirm={() => onAddCard()}
              closeModal={() => setIsModalOpen(!isModalOpen)}
            />
          </Box>
        ),
      },
    ];
    if (!!hasBankClaim || !nationalId) {
      return tabArray;
    }
    tabArray.push({
      label: t('payments:bankClaim.tabTitle'),
      id: 'netbanki',
      onClick: () => setSelectedTab('netbanki'),
      panelContent: (
        <Box paddingY={5}>
          <AddBankClaim
            nationalId={nationalId}
            customerId={customerId}
            closeModal={() => setIsModalOpen(!isModalOpen)}
          />
        </Box>
      ),
    });

    return tabArray;
  };

  const nationalId = customerData?.customer?.nationalId;
  return (
    <Box paddingY={8}>
      <Grid gridTemplate={{ sm: 4, md: 12 }}>
        <GridItem gridColumn={{ sm: 'span12' }}>
          <Box
            paddingBottom={4}
            display="flex"
            flexDirection={{ sm: 'column', md: 'row' }}
            justifyContent="space-between"
          >
            <Box marginBottom={{ sm: 6, md: 0 }}>
              <Text variant="h6">{t('payer.settings.paymentOptions')}</Text>
            </Box>
            <SecondaryButton
              icon="add"
              onClick={() => setIsModalOpen(true)}
              text={t('payment.paymentMethod.addPaymentMethod')}
            />
          </Box>
        </GridItem>
        {getCardList().map(({ title, card, id }) => {
          return (
            <GridItem key={id} gridColumn={{ sm: 'span12', md: 'span6', lg: 'span4' }}>
              <Box marginBottom={4}>
                <PaymentInfoCard
                  title={title}
                  card={{ ...card }}
                  mainButton={{
                    text: t('payment.paymentMethod.moreInfo'),
                    icon: 'longArrowRight',
                    colorScheme: 'white',
                    dottedShadow: 'none',
                    renderAs: 'a',
                    href: `/beta/${customerId}/greidslumati/${id}`,
                  }}
                  menuItems={[
                    {
                      text: t('payment.paymentMethod.deletePaymentMethod'),
                      onClick: () => onToBeDeleted(id),
                    },
                  ]}
                />
              </Box>
            </GridItem>
          );
        })}
        <GridItem gridColumn={{ sm: 'span12' }}>
          <Text marginBottom={4} variant="h6">
            {t('payer.recipientEmail')}
          </Text>
          <Box display="flex">
            <Box width={{ sm: '50%', md: '100%' }} marginRight={4}>
              <Input
                id="email"
                name="Netfang"
                type="email"
                autoComplete="on"
                onChange={(e) => setReceptEmail(e.target.value)}
                label={t('user.email')}
              />
            </Box>
            <Box width={{ sm: '50%', md: '100%' }}>
              <MainButton text={t('payer.saveChanges')} onClick={() => alert(receptEmail)} />
            </Box>
          </Box>
        </GridItem>
      </Grid>
      <Modal
        ariaLabel="Add"
        isVisible={isModalOpen}
        onVisibilityChange={(isVisible) => setIsModalOpen(isVisible)}
      >
        <Box padding={{ sm: 2, md: 6 }} width="100%">
          <Tabs
            tabBaseId="greidslur"
            tabBaseLabel="Greiðslur"
            selectedTab={selectedTab.toString()}
            tabs={tabs()}
          />
        </Box>
      </Modal>
      <ConfirmDeleteModal
        isLoading={loadingDelete}
        onDelete={() => onDelete(paymentMethodId)}
        onClose={() => setIsDeleteOpen(false)}
        isVisible={isDeleteOpen}
        onVisibilityChange={(isVisible) => setIsDeleteOpen(isVisible)}
      />
    </Box>
  );
};
