import React, { useEffect, useState } from 'react';
import { Box, Carousel, InfoCard, Text, TextWithPill } from '@nova-hf/ui';
import Wrapper from 'components/app-layout/Wrapper';
import { Segment } from 'components/segment/Segment';
import { inject, observer } from 'mobx-react';
import Link from 'next/link';
import Authentication from 'store/authentication';
import UI from 'store/ui';
import { SearchHit, useSearchLazyQuery } from 'typings/graphql';
import { formatNationalId } from 'utils/helpers';
import { useTranslation } from 'utils/i18n';

import { SearchLoading } from './components/SearchLoading';
import { maybeStrippedQueryString, SearchContainer } from './containers/SearchContainer';

type PanelCardProps = {
  hit: SearchHit;
  onClick: (nationalId: string, subscriptionId?: string) => void;
};

const PanelCard = ({ hit, onClick }: PanelCardProps) => {
  const { t } = useTranslation('common');

  const getLinkForService = (hit: SearchHit) => {
    let link = '';
    if (hit.__typename === 'ServiceSearchResult' && !hit.isBeta) {
      link =
        hit.user?.nationalId === '9999999999'
          ? `/oskrad/thjonusta/${hit.id}`
          : `/${hit.user?.nationalId}/thjonusta/${hit.id}`;
    } else {
      link = `beta/${hit.user?.id}/thjonustur/${hit.id}`;
    }
    return link;
  };
  type GeneralHitType = {
    longTitle: string;
    description: string;
    pillTitle: string;
    pillSubtitle: string;
    nationalId: string;
    subscriptionId?: string;
    linkUrl: string;
    isBeta?: boolean;
  };
  let mappedHit: GeneralHitType;
  switch (hit.__typename) {
    case 'PersonSearchResult':
    case 'OrganizationSearchResult':
      mappedHit = {
        longTitle: hit.name,
        description: formatNationalId(hit.nationalId),
        pillTitle: hit.customer?.name ?? '',
        pillSubtitle: hit.customer?.email ?? '',
        nationalId: hit.customer?.nationalId ?? hit.nationalId,
        linkUrl: `/${hit.nationalId}/thjonustur`,
      };
      break;
    case 'ServiceSearchResult':
      mappedHit = {
        longTitle: hit.title,
        description: t(`search.status.${hit.status.toLocaleLowerCase()}`),
        pillTitle: hit.user?.name ?? '',
        pillSubtitle: hit.user?.nationalId ?? '',
        nationalId: hit.user?.nationalId ?? '',
        subscriptionId: hit.id,
        linkUrl: getLinkForService(hit),
        isBeta: hit.isBeta ?? false,
      };
      break;
    case 'RepairSearchResult':
      mappedHit = {
        longTitle: hit.title ?? '',
        description: hit.description ?? '',
        pillTitle: hit.customer?.name ?? '',
        pillSubtitle: '',
        linkUrl: `/beta/${hit.customer?.id}/vidgerdir/${hit.id}`,
        nationalId: hit.customer?.nationalId ?? '',
        subscriptionId: hit.id,
        isBeta: true,
      };
      break;
    default:
      mappedHit = {
        longTitle: '',
        description: '',
        pillTitle: '',
        pillSubtitle: '',
        nationalId: '',
        linkUrl: '',
      };
      break;
  }

  if (!mappedHit.longTitle) return null;

  return (
    <>
      {mappedHit.isBeta ? (
        <Box
          renderAs="a"
          style={{ cursor: 'pointer' }}
          marginBottom={3}
          height="100%"
          width="100%"
          onClick={() => (window.location.href = mappedHit.linkUrl)}
        >
          <InfoCard
            height="100%"
            color="pink"
            icon={{
              icon: 'happy',
            }}
            boxShadow="none"
            renderAs="button"
            longTitle={mappedHit.longTitle}
            description={mappedHit.description}
          >
            <TextWithPill
              titleVariant="eyebrowMedium"
              title={mappedHit.pillTitle}
              subtitle={mappedHit.pillSubtitle}
            />
          </InfoCard>
        </Box>
      ) : (
        <Box renderAs={Link} href={mappedHit.linkUrl} marginBottom={2} height="100%" width="100%">
          <InfoCard
            color="pink"
            height="100%"
            boxShadow="none"
            icon={{
              icon: 'happy',
            }}
            renderAs="button"
            longTitle={mappedHit.longTitle}
            description={mappedHit.description}
            onClick={() => onClick(mappedHit.nationalId, mappedHit?.subscriptionId)}
          >
            <TextWithPill
              titleVariant="eyebrowMedium"
              title={mappedHit.pillTitle}
              subtitle={mappedHit.pillSubtitle}
            />
          </InfoCard>
        </Box>
      )}
    </>
  );
};

type PanelProps = {
  hits: SearchHit[];
  onClick: (nationalId: string, subscriptionId?: string) => void;
};

const Panel = ({ hits, onClick }: PanelProps) => {
  if (!hits.length) return null;
  return (
    <Carousel hasNavigationButtons={false} childrenToLazyLoadAtATime={4}>
      {hits.map((h, i) => (
        <PanelCard key={i} hit={h} onClick={onClick} />
      ))}
    </Carousel>
  );
};

type LeitProps = {
  ui?: UI;
  authentication?: Authentication;
};

const Leit = ({ ui, authentication }: LeitProps) => {
  const { t } = useTranslation('common');
  const [searchTerm, setSearchTerm] = useState('');
  const [isSearching, setIsSearching] = useState(false);
  const [getResults, { data, loading }] = useSearchLazyQuery({
    onCompleted(data) {
      if (data?.search?.results.length) {
        setIsSearching(false);
      }
    },
    onError() {
      setIsSearching(false);
    },
  });

  const searchResultsLen =
    data?.search?.results.map((result) => result.hits.length).reduce((a, b) => a + b, 0) ?? 0;

  useEffect(() => {
    if (ui) {
      ui?.setHasSideMenu(false);
      ui?.setHasCustomerMenu(false);
    }
  }, []);

  useEffect(() => {
    const searchQuery = maybeStrippedQueryString(searchTerm);
    if (searchQuery) {
      getResults({ variables: { input: { query: searchQuery } } });
    }
  }, [searchTerm]);

  const handleSearchHitClick = (nationalId: string, subscriptionId?: string) => {
    if (nationalId !== '9999999999') {
      authentication?.setAccountInput(nationalId, subscriptionId);
    } else {
      authentication?.setAccountInput('', subscriptionId);
    }
  };

  return (
    <Wrapper header="dark">
      <Segment>
        <Box position="relative">
          <SearchContainer onIsSearching={setIsSearching} onDataComplete={setSearchTerm} />
          {(isSearching || loading) && !data?.search?.results.length && <SearchLoading />}
          {!!data?.search?.results.length && !!searchTerm && (
            <>
              <>
                {data && !searchResultsLen && (
                  <Box display="inline-flex" marginTop={8}>
                    <Text variant="pMediumRegular">{t('search.noResultsFor')}</Text>
                    &nbsp;
                    <Text variant="pMediumBold" color="pink">{`"${searchTerm}"`}</Text>
                  </Box>
                )}
                {data?.search.results.map((s) => {
                  if (!s.hits.length) return null;
                  return (
                    <Box key={s.index} marginY={8}>
                      <Box marginBottom={8}>
                        <Box display="flex" justifyContent="space-between" alignItems="center">
                          <Text variant="h6">
                            {t(`search.${s.index.toString().toLowerCase()}`)}
                          </Text>
                        </Box>
                      </Box>
                      {s.hits.length && (
                        <Panel onClick={handleSearchHitClick} hits={s.hits as SearchHit[]} />
                      )}
                      <Box
                        borderBottomStyle="solid"
                        borderColor="grey200"
                        borderWidth="1px"
                        paddingTop={8}
                      />
                    </Box>
                  );
                })}
              </>
              <Box
                display={{ sm: 'none', md: 'none', lg: 'inline-flex' }}
                position="absolute"
                top={5}
                right={0}
              >
                <Text variant="pMediumRegular">{t('search.showing')}</Text>&nbsp;
                <Text variant="pMediumBold" color="pink">
                  {searchResultsLen}
                </Text>
                &nbsp;
                <Text variant="pMediumRegular">{t('search.resultsFor')}</Text>&nbsp;
                <Text variant="pMediumBold" color="pink">{`"${searchTerm}"`}</Text>
              </Box>
            </>
          )}
        </Box>
      </Segment>
    </Wrapper>
  );
};

Leit.getInitialProps = () => {
  return {
    namespacesRequired: ['common'],
  };
};

export default inject('ui', 'authentication')(observer(Leit));
