import React, { useEffect } from 'react';
import { useQuery } from '@apollo/client';
import { Hero, HeroHeadline, HeroTitle, Subtitle } from '@nova-hf/ui';
import SVGActivityList from 'assets/svg/activitylist.svg';
import SVGAddService from 'assets/svg/addService.svg';
import SVGGlobe from 'assets/svg/globe.svg';
import SVGPhone from 'assets/svg/phone.svg';
import Refill from 'assets/svg/refill.svg';
import SVGRefillHistory from 'assets/svg/refillHistory.svg';
import SVGReport from 'assets/svg/report.svg';
import SVGSettings from 'assets/svg/settings.svg';
import SVGSummary from 'assets/svg/summary.svg';
import { HeroDock } from 'components/hero-dock/HeroDock';
import { HeroDockItem } from 'components/hero-dock/HeroDockItem';
import LinkWrapper from 'components/link-wrapper/LinkWrapper';
import NavigationPanel, { PanelItem, PanelList } from 'components/navigation-panel/NavigationPanel';
import HeroSubscription from 'containers/hero/HeroSubscription';
import { SUBSCRIPTION } from 'graphql/queries/subscription';
import { inject } from 'mobx-react';
import { useRouter } from 'next/router';
import Authentication from 'store/authentication';
import Profile from 'store/models/Profile';
import UI from 'store/ui';
import { IMenuList, IProfile, IRateplan, IUserData } from 'typings';
import { formatDate, formatFirstName, formatTel, profileColor } from 'utils/helpers';
import { useTranslation } from 'utils/i18n';
import SEO from 'utils/SEO';

import NovaTvHeroProfile from './NovaTvHeroProfile';

interface IHeroProps {
  subscriptionId: string;
  parentId?: string;
  subtitleLink?: string;
  color?: string;
  textColor?: string;
  background?: string;
  ui?: UI;
  authentication?: Authentication;
  href?: string;
  childSubscriptionId?: string;
}

interface IGreetingProps extends IHeroProps {
  profile: IProfile;
}

interface IPanelProps {
  list: Array<IMenuList>;
}

const getIcon = (type: string) => {
  switch (type) {
    case 'usage':
      return <SVGPhone />;
    case 'history':
      return <SVGActivityList />;
    case 'abroad':
      return <SVGGlobe />;
    case 'summary':
      return <SVGSummary />;
    case 'report':
      return <SVGReport />;
    case 'refillHistory':
      return <SVGRefillHistory />;
    case 'settings':
      return <SVGSettings />;
    case 'refill':
      return <Refill />;
    case 'addService':
      return <SVGAddService />;
  }
};

const ErrorComponent = ({ color, textColor, subscriptionId, href, background }: IHeroProps) => {
  const { t } = useTranslation('common');

  return (
    <Hero
      accentColor={color}
      subHero
      background={background}
      color={textColor}
      withDock
      lessPadding
    >
      <HeroHeadline accentColor={color}>
        <Subtitle
          col={12}
          color={textColor}
          leftAlign
          linkComponent={href ? <LinkWrapper href={href}> ... - {subscriptionId}</LinkWrapper> : ''}
        >
          ... - {subscriptionId}
        </Subtitle>
        <HeroTitle subHero color="dark">
          {t('hero.errorTitle')}
        </HeroTitle>
      </HeroHeadline>
    </Hero>
  );
};

// TODO: make a better loading component for Hero
const LoadingComponent = ({ color, textColor, background }: IHeroProps) => (
  <Hero
    isLoading
    accentColor={color}
    subHero
    background={background}
    color={textColor}
    withDock
    lessPadding
  >
    <HeroHeadline accentColor={color}>
      <Subtitle col={6} color="white">
        ...
      </Subtitle>
      <HeroTitle subHero color="dark">
        ...
      </HeroTitle>
    </HeroHeadline>
  </Hero>
);

const Greeting = ({
  subscriptionId,
  href,
  color,
  profile,
  textColor,
  background,
}: IGreetingProps) => {
  const { rateplan, name, title } = profile;

  const isRegistered = rateplan.typeId !== 'unregistered';

  const subtitleText = ((params: { rplan: IRateplan; profileTitle: string }) => {
    const { rplan, profileTitle } = params;

    switch (rplan.typeId) {
      case 'service_bundle':
      case 'vip_service_bundle':
        return `${profileTitle} - ${rateplan.title}${profile.isRouted ? ' - OCS' : ''}`;
      default:
        return `${rateplan.title} - ${profileTitle}${profile.isRouted ? ' - OCS' : ''}`;
    }
  })({ rplan: rateplan, profileTitle: title });

  return (
    <Hero
      accentColor={color}
      subHero
      background={background}
      color={textColor}
      withDock
      lessPadding
    >
      <SEO title={subtitleText} />
      <HeroHeadline accentColor={color}>
        <Subtitle
          col={12}
          color={textColor}
          leftAlign
          linkComponent={
            isRegistered && href ? (
              <LinkWrapper href={href}>
                {rateplan.title} - {subscriptionId}
              </LinkWrapper>
            ) : (
              ''
            )
          }
        >
          {subtitleText}
        </Subtitle>
        <HeroTitle subHero color="dark">
          {formatFirstName(name)}
        </HeroTitle>
      </HeroHeadline>
    </Hero>
  );
};

const Panel = ({ list }: IPanelProps) => {
  const { t } = useTranslation(['subscription', 'common', 'stillingar']);

  return (
    <PanelList linkType="link">
      {list.map((item: IMenuList) => {
        return (
          <PanelItem title={t(item.title)} href={item.href} key={item.id} newTab={item.newTab}>
            {item.subLinks && item.subLinks.length > 0 && (
              <PanelList linkType="subLink">
                {item.subLinks.map((subItem) => (
                  <PanelItem
                    title={t(subItem.title)}
                    href={subItem.href}
                    key={subItem.id}
                    newTab={subItem.newTab}
                  >
                    {subItem?.hoverLinks && subItem.hoverLinks.length > 0 && (
                      <PanelList linkType="hoverLink">
                        {subItem.hoverLinks?.map((hoverItem) => (
                          <PanelItem
                            title={hoverItem.title}
                            href={hoverItem.href}
                            key={hoverItem.id}
                            newTab={hoverItem.newTab}
                          />
                        ))}
                      </PanelList>
                    )}
                  </PanelItem>
                ))}
              </PanelList>
            )}

            {item.hoverLinks && item.hoverLinks.length > 0 && (
              <PanelList linkType="hoverLink">
                {item.hoverLinks.map((hoverItem) => (
                  <PanelItem
                    title={t(hoverItem.title)}
                    href={hoverItem.href}
                    key={hoverItem.id}
                    newTab={hoverItem.newTab}
                  />
                ))}
              </PanelList>
            )}
          </PanelItem>
        );
      })}
    </PanelList>
  );
};

const HeroFunctionContainer = ({
  color,
  background,
  subscriptionId,
  parentId,
  subtitleLink,
  ui,
  authentication,
  childSubscriptionId,
  ...rest
}: IHeroProps) => {
  const accountInput = authentication?.accountInput;
  const isStaff = authentication?.isStaff;
  const { t } = useTranslation('subscription');

  const textColor = background === 'dark' ? 'white' : 'dark';
  const router = useRouter();

  if (!router) {
    return null;
  }

  const { query } = router;

  const infoProps = {
    subscriptionId: formatTel(subscriptionId),
    color,
    textColor,
    background,
    ui,
    authentication,
    ...rest,
  };

  const defaultBackHref = `/${query.ssn}${subtitleLink}`;

  const { loading, error, data } = useQuery<IUserData>(SUBSCRIPTION, {
    variables: { subscriptionId, accountInput },
  });

  let profile: Profile | null = null;

  useEffect(() => {
    /*
      These ui updates are in a useEffect hook to prevent:
      Warning: Cannot update during and existing state transition
     */
    if (data?.me?.profiles?.[0]) {
      const p = new Profile(data?.me?.profiles?.[0]);
      ui?.setHasSideMenu(false);
      if (profile?.type === 'fiber') {
        ui?.setHasCustomerMenu(true);
      } else {
        ui?.setHasCustomerMenu(false);
      }
      ui?.setHeaderStyle(p.isNovaTV ? 'light' : 'dark');
      ui?.setPageColor(profileColor(p?.rateplan));
    }
  });

  if (!ui) return null;

  if (loading) {
    return <LoadingComponent {...infoProps} />;
  }
  if (error || !data?.me?.profiles || !data?.me?.profiles[0]) {
    return <ErrorComponent href={isStaff ? '/staff' : defaultBackHref} {...infoProps} />;
  }
  const {
    me: { email: primaryEmail, profiles },
  } = data;
  const { ssn, name, email: serviceContactEmail, accountSsn, accountName } = profiles[0];

  profile = new Profile(profiles[0]);

  const { rateplan, created } = profile;
  const rateplanColor = profileColor(rateplan);

  infoProps.color = rateplanColor;
  infoProps.ui?.setPageColor(rateplanColor);

  const isNovaTV = profile.isNovaTV;
  const heroSubNav = profile.getHeroSubNavigation(accountInput?.ssn ?? '', !!isStaff);

  if (profile.type === 'fiber') {
    return <HeroSubscription parentId={parentId} subscriptionId={subscriptionId} />;
  }

  return (
    <div>
      {isNovaTV ? (
        <NovaTvHeroProfile profile={profile} childSubscriptionId={childSubscriptionId} />
      ) : (
        <>
          <Greeting profile={profiles[0]} href={defaultBackHref} {...infoProps} />
          <HeroDock inverted subDock color={rateplanColor}>
            {heroSubNav.map((item: IMenuList) => {
              const isInSettings = item.id === 'settings' && router.asPath.includes('/stillingar');

              return (
                <HeroDockItem
                  key={item.id}
                  className={item.className}
                  title={t(item.title)}
                  href={item.href}
                  selected={isInSettings || item.href === router.asPath.split('?')[0]}
                  addService={item.addService}
                  icon={getIcon(item.id)}
                />
              );
            })}
          </HeroDock>
        </>
      )}
      {isStaff && (
        <NavigationPanel
          background={background}
          created={created && formatDate(created, 'dd.MM.yyyy')}
          customerLinkList={[
            {
              title: 'Notandi',
              ssn,
              name,
              address: `${data?.me?.userProfile?.streetAddress}, ${data?.me?.userProfile?.postalCode} ${data?.me?.userProfile?.city}`,
              onClick: () => authentication?.setAccountInput(ssn),
              email: serviceContactEmail,
              to: `/${ssn}/thjonustur`,
            },
            {
              title: 'Greiðandi',
              ssn: accountSsn,
              name: accountName,
              onClick: () => authentication?.setAccountInput(accountSsn),
              email: accountInput?.ssn === accountSsn || ssn === accountSsn ? primaryEmail : '',
              to: `/${accountSsn}/thjonustur`,
            },
          ].filter((l) => l.ssn !== '9999999999')}
          mainList={<Panel list={heroSubNav} />}
          otherList={<Panel list={profile.panelSubNav} />}
        />
      )}
    </div>
  );
};

export default inject('authentication', 'ui')(HeroFunctionContainer);
