import React, { useEffect, useState } from 'react';
import {
  Box,
  Datepicker,
  IconButton,
  LoadingBar,
  MainButton,
  Modal,
  NotificationBanner,
  Pill,
  Text,
} from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import { Emoji } from 'assets/images/mobile-signup';
import BaseWrapper from 'frisco/BaseWrapper/BaseWrapper';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';

import {
  MobileOrderStatus,
  MobilePortInStatus,
  MobileServiceStatus,
  useActivationTimeMobileOrderMutation,
  useMobileServiceOrderQuery,
  useMobileServicesQuery,
} from '../../../typings/graphql';
import { formatDate } from '../../../utils/helpers';

import EsimVirkjun from './EsimVirkjun';

type TransferNumberStatusProps = {
  phoneNumber?: string;
  isFlutningur?: boolean;
  getIfComplete?: (status: MobileOrderStatus, phoneNumber: string) => void;
  color?: MainColorType;
};

type MobileStatusBox = {
  hasLoadingBar: boolean;
  emoji: Emoji;
  title: string;
  description: string;
  hasTwoButtons: boolean;
  buttonText?: string;
};

const TransferNumberStatus = ({
  phoneNumber,
  isFlutningur,
  getIfComplete,
  color,
}: TransferNumberStatusProps) => {
  const router = useRouter();
  const { enqueueSnackbar } = useSnackbar();
  const isTakkSite = router?.pathname?.includes('takk');
  const [chosenDate, setChosenDate] = useState(new Date());
  const [showEsim, setShowEsim] = useState(false);
  const [showChooseDate, setShowChooseDate] = useState(false);
  const [stopPolling, setStopPolling] = useState(false);

  const { data: mobileServiceData } = useMobileServicesQuery({
    variables: {
      input: {
        phoneNumber: phoneNumber ?? '',
      },
    },
    skip: !phoneNumber,
    pollInterval: stopPolling ? 0 : 10000,
  });

  const serviceId =
    mobileServiceData?.mobileServices?.services?.find(
      (service) => service?.mobileStatus === MobileServiceStatus.Active,
    )?.id ?? undefined;

  const { data: orderData, refetch: mobileServiceOrderRefetch } = useMobileServiceOrderQuery({
    variables: {
      id: serviceId ?? '',
    },
    skip: !serviceId,
    pollInterval: stopPolling ? 0 : 5000,
  });

  const orderId = orderData?.mobileServiceOrder?.id;
  const orderStatus = orderData?.mobileServiceOrder?.mobileOrderStatus;

  const [changeActivationTime, { loading: activationTimeLoading }] =
    useActivationTimeMobileOrderMutation({
      onCompleted(data) {
        if (data) {
          enqueueSnackbar('Tókst að uppfæra flutningstíma', {
            variant: 'success',
          });
          mobileServiceOrderRefetch();
          setShowChooseDate(false);
        }
      },
      onError(error) {
        if (error) {
          enqueueSnackbar('Ekki tókst að uppfæra flutningstíma' + '' + error.message, {
            variant: 'error',
          });
        }
      },
    });

  const currentDate = orderData?.mobileServiceOrder?.mobilePortInOrder?.portInDate;

  const pendingConfig: MobileStatusBox = {
    emoji: 'wifi_disco',
    hasLoadingBar: true,
    title: 'Við erum að færa þig yfir',
    description:
      'Við erum að spjalla við fyrrverandi um hvernig er best að flytja þig til okkar. Gefðu okkur augnablik',
    buttonText: 'Setja upp eSIM',
    hasTwoButtons: true,
  };

  const noFlutningurConfig: MobileStatusBox = {
    emoji: 'checkMark',
    hasLoadingBar: false,
    title: 'Allt klárt!',
    description: 'Þú getur virkjað eSIM-kortið þitt strax hér fyrir neðan',
    hasTwoButtons: false,
    buttonText: 'Setja upp eSIM',
  };

  const mapPortInStatus: Record<MobilePortInStatus, MobileStatusBox> = {
    [MobilePortInStatus.Cancelled]: {
      emoji: 'cancel',
      hasLoadingBar: false,
      title: 'Hætt var við númeraflutning',
      description:
        'Obbobbobb. Þú hefur hætt við flutninginn. Ekkert mál, plön breytast. Ef þú vilt hætta við að hætta við geturðu heyrt í okkur hvenær sem er.',
      hasTwoButtons: false,
    },
    [MobilePortInStatus.Pending]: pendingConfig,
    [MobilePortInStatus.Done]: {
      emoji: 'checkMark',
      hasLoadingBar: false,
      title: 'Allt klárt!',
      description: 'Númeraflutningurinn er kominn í gegn og þú getur sett eSIMið þitt upp strax.',
      hasTwoButtons: false,
      buttonText: 'Setja upp eSIM',
    },
    [MobilePortInStatus.Registered]: pendingConfig,
    [MobilePortInStatus.Rejected]: {
      emoji: 'cancel',
      hasLoadingBar: false,
      title: 'Beiðni um flutning var hafnað',
      description: 'Hafðu samband við gamla fjarskiptafélagið þitt.',
      hasTwoButtons: false,
    },
    [MobilePortInStatus.InProgress]: !currentDate
      ? pendingConfig
      : {
          emoji: 'wifi_disco',
          hasLoadingBar: true,
          title: `Við færum þig ${formatDate(currentDate, 'd. MMM yyyy HH:mm')}`,
          description:
            'Allt er á áætlun til að allt gangi smurt þú missir ekki sambandið geturðu sett eSIMið upp strax.',
          hasTwoButtons: true,
          buttonText: 'Setja upp eSIM',
        },
    [MobilePortInStatus.Starting]: pendingConfig,
  };

  const currentStatus = isFlutningur
    ? mapPortInStatus[
        orderData?.mobileServiceOrder?.mobilePortInOrder?.status ?? MobilePortInStatus.Pending
      ]
    : noFlutningurConfig;

  const onButtonClick = () => {
    router.replace(
      {
        pathname: router.pathname,
        query: { ...router.query, phoneNumber },
      },
      undefined,
      { shallow: true },
    );
    setShowEsim(true);
  };

  const onSecondaryButtonClick = () => {
    setShowChooseDate(true);
  };

  const onConfirmDate = async () => {
    try {
      await changeActivationTime({
        variables: {
          input: { orderId: orderId ?? '', newPortInDateTime: chosenDate },
        },
      });
    } catch (error) {
      if (error instanceof Error) {
        enqueueSnackbar('Ekki tókst að uppfæra flutningstíma' + '' + error.message, {
          variant: 'error',
        });
      }
    }
  };

  useEffect(() => {
    if (
      orderStatus === MobileOrderStatus.Completed ||
      orderStatus === MobileOrderStatus.Rejected ||
      orderStatus === MobileOrderStatus.Cancelled ||
      orderStatus === MobileOrderStatus.Error
    ) {
      setStopPolling(true);
      if (getIfComplete && phoneNumber) {
        getIfComplete(orderStatus, phoneNumber);
      }
      if (!isFlutningur) {
        setStopPolling(true);
      }
    }
  }, [orderStatus]);

  const secondaryButtonText = () => {
    if (isTakkSite) {
      if (
        orderData?.mobileServiceOrder?.mobilePortInOrder?.status ===
          MobilePortInStatus.InProgress &&
        currentDate
      ) {
        return 'Breyta?';
      } else {
        return 'Seinka?';
      }
    } else {
      if (
        orderData?.mobileServiceOrder?.mobilePortInOrder?.status ===
          MobilePortInStatus.InProgress &&
        currentDate
      ) {
        return 'Breyta tíma';
      } else {
        return 'Seinka tíma';
      }
    }
  };

  return (
    <Box>
      {isTakkSite ? (
        <BaseWrapper
          color="grey100"
          hasBackground
          hasLoading={currentStatus?.hasLoadingBar}
          {...(!currentStatus?.hasTwoButtons && { emoji: currentStatus?.emoji })}
        >
          <Box
            display="flex"
            flexDirection="row"
            alignItems="center"
            justifyContent="space-between"
            marginTop={2}
          >
            <Text color="black100" marginBottom={1} variant={'pMediumBold'}>
              {currentStatus?.title}
            </Text>
            {currentStatus?.hasTwoButtons && (
              <Box marginBottom={1} renderAs="button" onClick={() => onSecondaryButtonClick()}>
                {secondaryButtonText() !== 'Breyta?' ? (
                  <Pill text={secondaryButtonText()} shape="rounded" size="small" color="grey200" />
                ) : (
                  <IconButton
                    color={'grey200'}
                    icon="edit"
                    hiddenButtonText="editButton"
                    hasBackgroundFilled
                  />
                )}
              </Box>
            )}
          </Box>
          <Text color="grey700" marginBottom={2} variant={'pSmallRegular'}>
            {currentStatus?.description}
          </Text>
          {currentStatus?.buttonText && (
            <Box display="flex" flexDirection="row" gap={2} justifyContent="center">
              <MainButton
                colorScheme="pink"
                text={currentStatus?.buttonText ?? ''}
                onClick={() => onButtonClick()}
              />
            </Box>
          )}
        </BaseWrapper>
      ) : (
        <Box width="100%">
          <NotificationBanner
            eyebrowText={'Farsími'}
            description={currentStatus?.description}
            icon="mobile"
            color={color ?? 'pink'}
            mainButtonColored={{
              icon: 'longArrowRight',
              text: currentStatus.buttonText,
              onClick: () => onButtonClick(),
            }}
            {...(currentStatus?.hasTwoButtons && {
              mainButtonWhite: {
                icon: 'calendar',
                text: secondaryButtonText(),
                onClick: () => onSecondaryButtonClick(),
              },
            })}
            title={currentStatus?.title}
            hasPingAlert
          >
            <Box width="100%">
              <LoadingBar color={color ?? 'pink'} progressBar={{ percentage: 100, thickness: 2 }} />
            </Box>
          </NotificationBanner>
        </Box>
      )}
      <Modal
        onVisibilityChange={(isVisible) => setShowEsim(isVisible)}
        isVisible={showEsim}
        ariaLabel={'EsimModal'}
      >
        <Box
          marginX="auto"
          display="flex"
          flexDirection="column"
          alignItems="flex-start"
          justifyContent="flex-start"
        >
          <Box marginBottom={-20} marginTop={5}>
            <Text variant="pLargeBold" color={'grey600'}>
              Virkja eSIM kort
            </Text>
            <Text variant="h5">{phoneNumber}</Text>
          </Box>
          <EsimVirkjun />
        </Box>
      </Modal>
      <Modal
        onVisibilityChange={(isVisible) => setShowChooseDate(isVisible)}
        isVisible={showChooseDate}
        ariaLabel={'DateModal'}
      >
        <Box width="100%" height="100%" display="flex" flexDirection="column">
          <Text>Veldu dagsetningu hér fyrir neðan</Text>
          <Datepicker
            inputId="datepicker"
            inputName="datepicker"
            color="pink"
            selected={chosenDate}
            minDate={new Date()}
            onSelect={(date: Date) => setChosenDate(date)}
          />
          <Text>{`Valin dagsetning er ${formatDate(chosenDate, 'dd.MM.yyyy')}`}</Text>
          <MainButton
            isLoading={activationTimeLoading}
            colorScheme="pink"
            text={'Staðfesta'}
            onClick={() => onConfirmDate()}
          />
        </Box>
      </Modal>
    </Box>
  );
};

export default TransferNumberStatus;
