import React, { useEffect, useState } from 'react';
import { NetworkStatus } from '@apollo/client';
import {
  Box,
  Grid,
  GridItem,
  IconType,
  InfoCard,
  ListBase,
  makeToast,
  Text,
  ThemeColorType,
} from '@nova-hf/ui';
import { serviceSimpleNameMap } from 'beta/utils/helpers';
import { parseMainColor } from 'beta/utils/typeGuards';
import { useRouter } from 'next/router';
import {
  CreditControl,
  CreditControlSettingInput,
  ServiceType,
  useAddServiceToContractMutation,
  useContractSlotsQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

import { ErrorBanner } from '../../components/error/ErrorBanner';
import { CreditControlModal } from '../creditControl-modal/CreditControlModal';

export type ServiceItems = {
  key: string;
  serviceTitle?: string;
  serviceDescription?: string;
  serviceType?: string;
};

type ServiceListProps = {
  icon: IconType;
  color: ThemeColorType;
  services: ServiceItems[];
  onClick?: boolean;
  customerId?: string;
  text?: string;
  type?: ServiceType;
};

const ServiceList = ({ icon, color, services, onClick, text, type }: ServiceListProps) => {
  const { t } = useTranslation('alltSaman');
  const router = useRouter();
  const [showCreditControlModal, setShowCreditControlModal] = useState<boolean>(false);
  const [creditControls, setCreditControls] = useState<CreditControl[]>();
  const targetContractId = (router.query.contractId as string) ?? '';
  const [serviceId, setServiceId] = useState<string>('');

  const {
    data: slotsData,
    loading: slotsLoading,
    error: slotsError,
    networkStatus: slotsNetworkStatus,
    refetch: slotsRefetch,
  } = useContractSlotsQuery({
    variables: {
      input: {
        contractId: targetContractId.toString(),
      },
    },
  });

  const getCreditControls = () => {
    const selectedVariant = slotsData?.contractSlots?.find((contract) =>
      contract?.variants.find(
        (variant) =>
          variant.__typename === 'ProvisionedSubscriptionVariant' && variant.serviceType === type,
      ),
    );
    if (selectedVariant) setCreditControls(selectedVariant.variants[0].creditControls);
  };
  const [serviceToContract] = useAddServiceToContractMutation({
    onCompleted: (data) => {
      makeToast.success(t('alltSaman.addToPackSuccess'), '');

      if (data) {
        router.push(`/beta/${router.query.customerId}/askriftir/${targetContractId}`);
      }
    },
    onError(error) {
      makeToast.danger(t('alltSaman.addToPackFail'), error.message);
    },
  });

  const handleToggle = (id: string) => {
    if (id) setServiceId(id);
  };

  const handleConfirm = (creditControlInput?: CreditControlSettingInput[]) => {
    try {
      serviceToContract({
        variables: {
          input: {
            contractId: targetContractId,
            serviceId: serviceId,
            moveConnectedContractItems: true,
            creditControlSettings: creditControlInput ?? [],
          },
        },
      });
      setShowCreditControlModal(false);
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger('error', error.message);
      }
    }
  };

  useEffect(() => {
    getCreditControls();
  }, []);

  useEffect(() => {
    if (serviceId) {
      creditControls && creditControls.length > 0
        ? setShowCreditControlModal(true)
        : handleConfirm(creditControls);
    }
  }, [serviceId]);

  if (slotsLoading || slotsError) {
    return (
      <>
        <ErrorBanner
          eyebrowTexts={[
            t('errors:thjonustur.eyebrows.1'),
            t('errors:thjonustur.eyebrows.2'),
            t('errors:thjonustur.eyebrows.3'),
          ]}
          titles={[
            t('errors:thjonustur.titles.1'),
            t('errors:thjonustur.titles.2'),
            t('errors:thjonustur.titles.3'),
          ]}
          descriptions={[
            t('errors:thjonustur.descriptions.1'),
            t('errors:thjonustur.descriptions.2'),
            t('errors:thjonustur.descriptions.3'),
          ]}
          icon="zap"
          color="attention"
          showLoading={slotsLoading || slotsNetworkStatus === NetworkStatus.refetch}
          refetchButton={{
            text: t('errors:buttons.refresh'),
            icon: 'refresh',
            onClick: () => slotsRefetch(),
          }}
          loadingComponent={
            <>
              <ListBase isLoading gap={3} />
              <ListBase isLoading gap={3} />
              <ListBase isLoading />
            </>
          }
        />
      </>
    );
  }

  return (
    <>
      <Box marginBottom={2}>
        <Text variant="subtitleBold">{text}</Text>
      </Box>
      <Grid gridTemplate={[1, 2, 2]} rowGap={{ sm: 3, lg: 3 }}>
        {services?.map((service) => (
          <Box key={service.key} marginBottom={2}>
            <GridItem gridColumn={{ sm: 'span3', lg: 'span3', xl: 'span2' }}>
              <InfoCard
                icon={{
                  icon: icon,
                }}
                color={parseMainColor(color ?? 'pink', 'pink')}
                dottedShadow="none"
                shortTitle={service.serviceTitle}
                description={service.serviceDescription}
                coloredText={serviceSimpleNameMap(type)}
                renderAs={onClick ? 'button' : undefined}
                onClick={() => handleToggle(service.key)}
              />
            </GridItem>
          </Box>
        ))}
      </Grid>
      <CreditControlModal
        isVisible={showCreditControlModal}
        onVisibilityChange={(isVisible: boolean) => setShowCreditControlModal(isVisible)}
        onConfirm={(creditControlInput: CreditControlSettingInput[]) =>
          handleConfirm(creditControlInput)
        }
        creditControls={creditControls}
        color={color}
      />
    </>
  );
};

export default ServiceList;
