import React, { useEffect, useState } from 'react';
import {
  Box,
  EmptyMessage,
  Grid,
  GridItem,
  Icon,
  LoadingPlaceholder,
  Menu as NavigationDropdown,
  Text,
  ThemeColorType,
} from '@nova-hf/ui';
import { SpaceType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import { startOfMonth } from 'date-fns';
import { capitalize, uniq } from 'lodash';
import Authentication from 'store/authentication';
import { SummaryItem, useSummaryLazyQuery } from 'typings/graphql';
import { formatDate, formatPrice, getMonths } from 'utils/helpers';
import { useTranslation } from 'utils/i18n';

interface MonthlySummaryProps {
  color?: ThemeColorType;
  subscriptionId: string;
  authentication?: Authentication;
}

export const MonthlySummary = ({ color, subscriptionId, authentication }: MonthlySummaryProps) => {
  const { t } = useTranslation('subscriptions');
  const [date, setDate] = useState(new Date());

  if (!authentication) return null;

  const [getSummaryItems, { loading, error, data }] = useSummaryLazyQuery();

  useEffect(() => {
    if (date && authentication) {
      getSummaryItems({
        variables: {
          accountInput: authentication?.accountInput,
          date: date,
          subscriptionId,
        },
      });
    }
  }, [date]);

  if (loading) {
    return <LoadingMonthlySummary />;
  }

  if (error || !data || !data.me) {
    return null;
  }

  const {
    me: { profiles },
  } = data;

  const currentProfile = profiles?.find((p) => p.subscriptionId === subscriptionId);

  if (!currentProfile) {
    return null;
  }

  const { summary } = currentProfile;

  const usage = summary?.usage;
  const totalSum = summary?.totalSum;

  const navigationDropdownItems = () => {
    const dateTime = date ? new Date(date) : new Date();
    const currDate = dateTime || new Date();

    return uniq(
      getMonths(new Date(), 5)
        .reverse()
        .map(({ month, date }: { month: string; date: Date }) => {
          return {
            text: capitalize(month),
            isActive: currDate.getMonth() === date.getMonth(),
            onClick: () => setDate(startOfMonth(date)),
          };
        }),
    );
  };

  return (
    <Box marginY={8} width="100%">
      <Box
        display="flex"
        justifyContent="space-between"
        flexDirection={['column', 'row']}
        width="100%"
        marginY={6}
      >
        <Text variant="h6">{t('monthlyUsageSummary.headerTitle')}</Text>
        <Box marginY={[3, 0]}>
          <NavigationDropdown
            color={color}
            disclosure={
              <Box
                display="inline-flex"
                alignItems="center"
                gap={1}
                renderAs="button"
                boxShadow={{ focusVisible: 'focused' }}
              >
                <Text variant="pMediumBold">{capitalize(formatDate(date, 'MMMM'))}</Text>
                <Icon icon="arrowDown" color={color} />
              </Box>
            }
            items={navigationDropdownItems()}
            label="select month"
          />
        </Box>
      </Box>
      {summary && !!summary.usage?.length ? (
        <>
          <Grid
            gridTemplate={{ sm: 6, md: 12 }}
            rowGap={{ sm: 2, lg: 3 }}
            columnGap={{ sm: 1, md: 2 }}
          >
            <GridItem gridColumn={{ sm: 'span2', md: '1/5' }}>
              <Text variant="eyebrowMedium" color="grey400">
                {t('monthlyUsageSummary.overview')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: '3/4', md: '6/8' }}>
              <Text renderAs="p" variant="eyebrowMedium" color="grey400" textAlign="right">
                {t('monthlyUsageSummary.usage')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: '5/7', md: '9/12' }}>
              <Text renderAs="p" variant="eyebrowMedium" color="grey400" textAlign="right">
                {t('monthlyUsageSummary.total')}
              </Text>
            </GridItem>
            <GridItem gridColumn={{ sm: 'span6', md: 'span12' }}>
              <Box style={{ height: '1px' }} backgroundColor="grey200"></Box>
            </GridItem>
            {!!usage?.length && <SummaryListDetails items={usage} level={1} />}
            <GridItem gridColumn={{ sm: 'span2', md: '1/8' }}>
              <Text variant="pMediumBold"> {t('monthlyUsageSummary.total')}</Text>
            </GridItem>
            <GridItem gridColumn={{ sm: '5/7', md: '9/12' }}>
              <Text renderAs="p" variant="pMediumBold" textAlign="right">
                {formatPrice(totalSum ?? 0)}
              </Text>
            </GridItem>
          </Grid>
        </>
      ) : (
        <EmptyMessage
          title="Engin samantekt"
          description={`Engin samantekt fannst fyrir ${formatDate(date, 'MMMM')}`}
        />
      )}
    </Box>
  );
};

type SummaryListItemProps = {
  items: SummaryItem[];
  level: number;
};
const SummaryListDetails = ({ items, level }: SummaryListItemProps) => {
  return (
    <>
      {items.map(
        ({
          showChildren,
          billedUnit,
          measureUnit,
          displayUnits,
          children,
          displayText,
          amount,
        }) => (
          <>
            <>
              <GridItem gridColumn={{ sm: '1/2', md: '1/5' }}>
                <Text
                  variant={level === 1 ? 'pMediumBold' : 'pMediumRegular'}
                  marginLeft={level === 2 ? 2 : ((level + 1) as SpaceType)}
                >
                  {displayText}
                </Text>
              </GridItem>
              {displayUnits && billedUnit && (
                <GridItem gridColumn={{ sm: '3/4', md: '6/8' }}>
                  <Text variant={level === 1 ? 'pMediumBold' : 'pMediumRegular'} textAlign="right">
                    {billedUnit && billedUnit} {measureUnit}
                  </Text>
                </GridItem>
              )}
              {!isNaN(amount!) && (
                <GridItem gridColumn={{ sm: '5/7', md: '9/12' }}>
                  <Text
                    renderAs="p"
                    variant={level === 1 ? 'pMediumBold' : 'pMediumRegular'}
                    textAlign="right"
                  >
                    {formatPrice(amount ?? 0)}
                  </Text>
                </GridItem>
              )}
            </>
            {showChildren && !!children?.length && (
              <SummaryListDetails items={children} level={level + 1} />
            )}
          </>
        ),
      )}
      {level === 2 && (
        <GridItem gridColumn={{ sm: 'span6', md: 'span12' }}>
          <Box style={{ height: '1px' }} backgroundColor="grey200"></Box>
        </GridItem>
      )}
    </>
  );
};

const LoadingMonthlySummary = () => (
  <>
    <Box display="inline-flex" justifyContent="space-between" width="100%" marginY={6}>
      <LoadingPlaceholder height={4} width={'5/12'} />
    </Box>
    <Box marginBottom={6}>
      <Grid gridTemplate={{ sm: 12 }} rowGap={{ sm: 2, lg: 3 }}>
        <GridItem gridColumn={{ sm: 'span6' }}>
          <LoadingPlaceholder height={2} width={'100%'} />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span3' }}>
          <LoadingPlaceholder height={2} width={'100%'} />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span3' }}>
          <LoadingPlaceholder height={2} width={'100%'} />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span12' }}>
          <Box style={{ height: '1px' }} backgroundColor="grey200"></Box>
        </GridItem>
        <GridItem gridColumn={{ sm: 'span9' }}>
          <LoadingPlaceholder height={2} width={'100%'} />
        </GridItem>
        <GridItem gridColumn={{ sm: 'span3' }}>
          <LoadingPlaceholder height={2} width={'100%'} />
        </GridItem>
      </Grid>
    </Box>
  </>
);
