import React, { useEffect, useState } from 'react';
import { NetworkStatus, useQuery } from '@apollo/client';
import {
  Box,
  CardBase,
  Checkbox,
  Grid,
  GridItem,
  Icon,
  ListBase,
  ListCard,
  Menu as NavigationDropdown,
  MultiSelectBanner,
  Text,
  useViewport,
} from '@nova-hf/ui';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import ContractsHeader from 'beta/components/contracts-header/ContractsHeader';
import { ErrorBanner } from 'beta/components/error/ErrorBanner';
import PaginationContainer from 'beta/components/layouts/Pagination';
import Wrapper from 'components/app-layout/Wrapper';
import Hero from 'containers/hero/Hero';
import { uniq, uniqBy } from 'lodash';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import Authentication from 'store/authentication';
import Hradleid from 'store/hradleid';
import UI from 'store/ui';
import { formatPrice, isCompany } from 'utils/helpers';
import { useTranslation } from 'utils/i18n';
import SEO from 'utils/SEO';

import { IContext } from '../../beta/typings/context';
import { SUBSCRIPTIONACCOUNT } from '../../graphql/queries/subscriptionAccount';
import { IUserData } from '../../typings';
import { Department, Rateplan, Status, useSubscriptionsQuery } from '../../typings/graphql';

type FjoldaskraningProps = {
  ui: UI;
  authentication: Authentication;
  hradleid: Hradleid;
};

const Fjoldaskraning = ({ ui, authentication, hradleid }: FjoldaskraningProps) => {
  const { t } = useTranslation(['services', 'errors', 'multi']);
  const router = useRouter();
  const ssn = router?.query?.ssn;
  const isStaff = authentication?.isStaff;
  const isCompanySsn = ssn ? isCompany(ssn.toString()) : false;
  const { accountInput } = authentication;
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(30);
  const [checked, setChecked] = useState<string[]>([]);
  const currentVariant = router?.query?.variant?.toString() ?? '';
  const [selectedVariant, setSelectedVariant] = useState(currentVariant);
  const currentDepartment = router?.query?.department?.toString() ?? '';
  const [selectedDepartment, setSelectedDepartment] = useState(currentDepartment);
  const [variantName, setVariantName] = useState('');
  const { isLarge, isXLarge, isMedium } = useViewport();
  const isMobile = !isLarge && !isXLarge && !isMedium;
  const widthForBanner = isMobile ? '100%' : 'calc(100% - 266px)';
  const { data: departmentData } = useQuery<IUserData>(SUBSCRIPTIONACCOUNT, {
    variables: { accountInput, servicesRequired: false },
  });
  const { data, loading, error, networkStatus, refetch } = useSubscriptionsQuery({
    variables: {
      subscriptionsInput: {
        page: page,
        perPage: perPage,
        onlyActive: true,
        forBulkMethods: true,
        rateplanId: selectedVariant,
        departmentId: selectedDepartment,
      },
      accountInput,
    },
    ssr: false,
    skip: !authentication,
  });

  const totalSubs = data?.me?.subscriptions?.pageInfo?.totalCount;
  const subscriptions = data?.me?.subscriptions?.subscriptions;
  const departmentsInList = subscriptions
    ?.filter(
      (subscription) => subscription.accountName !== null && subscription.accountName !== undefined,
    )
    .map((subscription) => subscription.accountName);
  const departments = departmentData?.me?.departments?.filter(
    (department) =>
      department !== null &&
      department !== undefined &&
      departmentsInList?.includes(department?.name),
  );
  const uniqueDepartments = uniq(departments);
  const handleSettingSelectedDepartment = (department: Department) => {
    const query = department ? { ...router.query, department: department.id } : { ...router.query };
    router.replace({
      query,
    });
  };
  const allDepartments = {
    text: t('services:departmentFilterTitle'),
    departmentId: '',
    onClick: () => {
      const { department, ...remainingQuery } = router.query; // eslint-disable-line no-unused-vars
      router.replace({
        query: remainingQuery,
      });
      setSelectedDepartment('');
    },
    isActive: selectedDepartment === '',
    color: 'pink',
  };
  const departmentFilters = [
    ...uniqueDepartments.map((department) => ({
      text: department.name,
      departmentId: department.id,
      onClick: () => {
        !!department && handleSettingSelectedDepartment(department);
        setSelectedDepartment(department?.id);
      },
      isActive: department.id === selectedDepartment,
      color: 'pink',
    })),
    allDepartments,
  ];
  const variants = subscriptions
    ?.map((sub) => sub?.rateplan)
    ?.filter((variant) => variant !== null && variant !== undefined);
  const uniqueVariants = uniq(variants);
  const handleSettingSelectedVariant = (variant: Rateplan) => {
    setVariantName(variant?.shortTitle);
    const query = variant ? { ...router.query, variant: variant?.id } : { ...router.query };
    router.replace({
      query,
    });
  };
  const allVariants = {
    text: t('variantFilterTitle'),
    variantId: '',
    onClick: () => {
      const { variant, ...remainingQuery } = router.query; // eslint-disable-line no-unused-vars
      router.replace({
        query: remainingQuery,
      });
      setSelectedVariant('');
    },
    isActive: selectedVariant === '',
    color: 'pink',
  };

  const variantFilters = [
    ...uniqueVariants.map((variant) => ({
      text: variant?.shortTitle,
      variantId: variant?.id,
      onClick: () => {
        !!variant && handleSettingSelectedVariant(variant);
        setSelectedVariant(variant?.id ?? '');
      },
      isActive: variant?.id === selectedVariant,
      color: 'pink',
    })),
    allVariants,
  ];
  const handleCheck = (phoneNumber: string) => {
    setChecked((prevChecked) => {
      if (prevChecked?.includes(phoneNumber)) {
        return prevChecked?.filter((num) => num !== phoneNumber);
      } else {
        return [...prevChecked, phoneNumber];
      }
    });
  };
  const rateplanMap = (rateplan: string): MainColorType => {
    if (rateplan?.toLowerCase().includes('áskrift')) {
      return 'ocean';
    } else {
      return 'pink';
    }
  };
  const statusMap = (status: Status) => {
    if (status === Status.Active) {
      return {
        text: t('multi:multi.active'),
        color: 'success',
      };
    }
    if (status === Status.B1w) {
      return {
        text: 'B1w',
        color: 'attention',
      };
    }
    if (status === Status.B2w) {
      return {
        text: 'B2w',
        color: 'warning',
      };
    } else {
      return {
        text: 'Unknown',
        color: 'warning',
      };
    }
  };

  const uniqSubs = uniqBy(subscriptions, 'subscriptionId').map((sub) => sub.subscriptionId);

  const getDepartmentName = (id: string) => {
    const department = departments?.find((d) => d?.id === id);
    return department?.name;
  };

  const getVariantTitle = (id: string) => {
    const variant = uniqueVariants?.find((v) => v?.id === id);
    return variant?.shortTitle;
  };

  const handleChooseAll = () => {
    if (ui.showContactBubble) {
      ui.setShowContactBubble(false);
    }
    const allAreChecked = checked.length === uniqSubs?.length;
    if (uniqSubs?.length && !allAreChecked) {
      setChecked(uniqSubs);
    } else {
      setChecked([]);
    }
  };

  const buttonClick = () => {
    if (perPage !== totalSubs) {
      setPerPage(totalSubs ?? 30);
    }
    if (perPage === totalSubs) {
      setPerPage(30);
    }
  };

  const handleMenuSelection = (flow: string) => {
    router.push(`/${ssn}/fjoldaskraning/${flow}`);
  };

  const iconClick = () => {
    setChecked([]);
  };

  useEffect(() => {
    hradleid.setSubscriptionIds(checked);
    if (ui.showContactBubble) {
      ui.setShowContactBubble(false);
    }
  }, [checked]);

  useEffect(() => {
    if (ui.hasMultiMenu) {
      ui.setHasMultiMenu(false);
    }
  }, []);

  useEffect(() => {
    if (!variantName && router?.query?.variant) {
      setVariantName(router?.query?.variant.toString());
    }
  }, [router?.query?.variant, router?.query?.department]);

  useEffect(() => {
    if (router.query.page !== page.toString()) {
      router.push(
        {
          pathname: router.pathname,
          query: { ...router.query, page: page.toString() },
        },
        undefined,
        { shallow: true },
      );
    }
  }, [page]);

  if (!authentication || !authentication?.isStaff) return;

  if (loading || error || !subscriptions || !subscriptions[0])
    return (
      <>
        <Wrapper noFooter>
          <SEO title={t('multi:multi.multiActions')} />
          <Hero
            title={t('multi:multi.multiActions')}
            color={'pink'}
            authentication={authentication}
            ui={ui}
          />
          <Box marginX={11} marginTop={2}>
            {loading && <ContractsHeader title={t('loadingTitle')} />}
            <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={loading || networkStatus === NetworkStatus.refetch}
              refetchButton={{
                text: t('errors:buttons.refresh'),
                icon: 'refresh',
                onClick: () => refetch(),
              }}
              loadingComponent={
                <>
                  <ListBase isLoading gap={3} />
                  <ListBase isLoading gap={3} />
                  <ListBase isLoading />
                </>
              }
            />
          </Box>
        </Wrapper>
      </>
    );

  return (
    <Wrapper noFooter>
      <SEO title={t('multi:multi.multiActions')} />
      <Hero
        title={t('multi:multi.multiActions')}
        color={'pink'}
        authentication={authentication}
        ui={ui}
      />
      <Box
        display="flex"
        flexDirection="row"
        alignItems="center"
        justifyContent="flex-end"
        marginX={11}
        marginY={3}
        gap={2}
      >
        {uniqueDepartments && uniqueDepartments?.length > 0 && (
          <NavigationDropdown
            color="pink"
            disclosure={
              <Box
                display="inline-flex"
                alignItems="center"
                gap={1}
                renderAs="button"
                boxShadow={{ focusVisible: 'focused' }}
              >
                <Text variant="pMediumBold">
                  {selectedDepartment && selectedDepartment.length
                    ? getDepartmentName(selectedDepartment)
                    : t('departmentFilterTitle')}
                </Text>
                <Icon icon="arrowDown" color="pink" />
              </Box>
            }
            items={departmentFilters}
            label="select"
          />
        )}
        {uniqueVariants && uniqueVariants?.length > 0 && (
          <NavigationDropdown
            color="pink"
            disclosure={
              <Box
                display="inline-flex"
                alignItems="center"
                gap={1}
                renderAs="button"
                boxShadow={{ focusVisible: 'focused' }}
              >
                <Text variant="pMediumBold">
                  {selectedVariant && selectedVariant.length
                    ? getVariantTitle(selectedVariant)
                    : t('variantFilterTitle')}
                </Text>
                <Icon icon="arrowDown" color="pink" />
              </Box>
            }
            items={variantFilters}
            label="select"
          />
        )}
      </Box>
      {isXLarge && (
        <Box
          padding={3}
          marginX={11}
          marginTop={2}
          display="flex"
          flexDirection="row"
          alignItems="center"
          justifyContent="flex-start"
          boxShadow={'normal'}
          backgroundColor="white"
        >
          <Grid gridTemplate={{ xl: 9 }} alignItems="center">
            <GridItem gridColumn={{ xl: 'span2' }}>
              <Box alignItems="center" display="flex" flexDirection="row" gap={8}>
                <Box display="flex" gap={1} flexDirection="column" alignItems="center">
                  <Checkbox
                    isChecked={checked.length === subscriptions.length}
                    type="checked"
                    color="pink"
                    onChange={() => {
                      handleChooseAll();
                    }}
                  />
                  <Text variant="pXSmallBold">{t('services:multiSelect.selectAll')}</Text>
                </Box>
                <Text variant="eyebrowMedium">{t('multi:multi.phoneNumber')}</Text>
              </Box>
            </GridItem>
            <GridItem gridColumn={{ xl: 'span2' }}>
              <Text variant="eyebrowMedium">{t('services:multiSelect.info')}</Text>
            </GridItem>
            <GridItem gridColumn={{ xl: 'span2' }}>
              <Text variant="eyebrowMedium">{t('services:multiSelect.service')}</Text>
            </GridItem>
            <GridItem gridColumn={{ xl: 'span2' }}>
              <Text variant="eyebrowMedium">{t('services:multiSelect.cost')}</Text>
            </GridItem>
            <GridItem gridColumn={{ xl: 'span1' }}></GridItem>
          </Grid>
        </Box>
      )}
      <Box marginY={6}>
        {subscriptions?.map((sub, index) => (
          <Box
            marginX={11}
            marginBottom={index === subscriptions.length - 1 ? 10 : 3}
            key={sub?.subscriptionGuid}
          >
            <ListCard
              button={{
                icon: 'longArrowRight',
                onClick: () =>
                  router.push(`/${router?.query?.ssn}/thjonusta/${sub?.subscriptionId}`),
                text: t('multi:multi.look'),
              }}
              checkBox={{
                onChange: () => handleCheck(sub?.subscriptionId),
                isChecked: checked?.includes(sub?.subscriptionId),
                type: 'checked',
              }}
              color={rateplanMap(sub.rateplan?.title ?? '')}
              hasBorder
              icon="mobile"
              isActive
              tag={{
                color: statusMap(sub?.statusCode)?.color as MainColorType,
                text: statusMap(sub?.statusCode)?.text,
              }}
            >
              <Box display="flex" flexDirection="row" alignItems="center">
                <Box width="2/12" paddingRight={2}>
                  <Text variant="pMediumBold">{sub?.subscriptionId}</Text>
                </Box>
                <Box width="4/12" paddingRight={2}>
                  <Text variant="pMediumBold">{sub?.name}</Text>
                  <Text variant="pSmallRegular">{`${t(
                    'multi:multi.paidBy',
                  )} ${sub?.accountName}`}</Text>
                </Box>
                <Box width="4/12" paddingRight={2}>
                  <Text variant="pMediumBold">{sub?.rateplan?.title}</Text>
                </Box>
                <Box width="2/12">
                  <Text variant="pMediumBold">{formatPrice(sub?.rateplan?.price ?? 0)}</Text>
                </Box>
              </Box>
            </ListCard>
          </Box>
        ))}
        <Box marginX={11} display="flex" justifyContent="center" width="10/12">
          <PaginationContainer
            buttonText={t('services:services.seeAll', { total: totalSubs })}
            color={'pink'}
            page={page}
            perPage={perPage}
            onSelectPage={setPage}
            total={totalSubs ?? 0}
            onButtonClick={buttonClick}
            isCondensedView={perPage !== totalSubs}
          />
        </Box>
      </Box>

      <Box bottom={0} position="fixed" style={{ width: widthForBanner }}>
        {checked?.length > 0 && (
          <MultiSelectBanner
            count={checked?.length}
            icon="close"
            isOnBottom={true}
            iconClick={() => iconClick()}
            tooltip={{
              children: (
                <CardBase borderColor="grey200" dottedShadow="none" hasBorder>
                  <Box padding={2}>
                    <Text marginBottom={1} variant="pSmallBold">
                      {t('multiSelect.tooltipTitle')}
                    </Text>
                    <Text marginBottom={1} variant="pXSmallRegular">
                      {t('multiSelect.tooltipInfo')}
                    </Text>
                  </Box>
                </CardBase>
              ),
              placement: 'bottom-end',
              shouldShowOnHover: true,
              color: 'pink',
            }}
            menuItems={[
              isCompanySsn
                ? {
                    onClick: () => {
                      handleMenuSelection('thak');
                    },
                    text: t('multiMethods.roof'),
                  }
                : null,
              {
                onClick: () => {
                  handleMenuSelection('payer');
                },
                text: t('multiMethods.payer'),
              },
              isCompanySsn
                ? {
                    onClick: () => {
                      handleMenuSelection('deild');
                    },
                    text: t('multiMethods.department'),
                  }
                : null,
              {
                onClick: () => {
                  handleMenuSelection('uppsogn');
                },
                text: 'Uppsögn',
              },
              isStaff
                ? {
                    onClick: () => {
                      handleMenuSelection('thjonustuleid');
                    },
                    text: t('multiMethods.pack'),
                  }
                : null,
              isStaff
                ? {
                    onClick: () => {
                      handleMenuSelection('notendabreyting');
                    },
                    text: 'Notendabreyting',
                  }
                : null,
              {
                onClick: () => {
                  handleMenuSelection('addPack');
                },
                text: 'Hringt til útlanda',
              },
            ].filter(Boolean)}
          />
        )}
      </Box>
    </Wrapper>
  );
};

Fjoldaskraning.getInitialProps = ({ pathname }: IContext) => {
  return {
    pathname,
    namespacesRequired: ['services', 'errors', 'multi'],
  };
};

export default inject('ui', 'authentication', 'hradleid')(observer(Fjoldaskraning));
