import * as React from 'react';
import { EmptyMessage } from '@nova-hf/ui';
import DateSVG from 'assets/svg/date.svg';
import { UsageBoxItem } from 'components/usage/UsageBoxItem';
import { UsageBoxItemLoading } from 'components/usage/UsageBoxItemLoading';
import UsageQuery from 'graphql/queries/usage';
import { isEmpty, sortBy } from 'lodash';
import { action, makeObservable } from 'mobx';
import { inject, observer } from 'mobx-react';
import Profile from 'store/models/Profile';
import UsagePack from 'store/models/UsageInfo';
import { IAlert, IAutoRefill, IPackInfo, IUsagePack } from 'typings';
import { distanceToDate, formatPrice, formatTel, profileColor } from 'utils/helpers';
import { WithTranslation, withTranslation } from 'utils/i18n';

import Authentication from '../../store/authentication';

interface IUsageProps extends WithTranslation {
  profile: Profile;
  onSelect(packIndex: number): any;
  selectedPack?: string;
  allowEmptyUsage?: boolean;
  authentication?: Authentication;
}

class Usage extends React.Component<IUsageProps> {
  constructor(props: IUsageProps) {
    super(props);

    makeObservable(this, {
      parseAlerts: action,
      autoRefillAlertValue: action,
    });
  }

  parseAlerts(alerts: Array<IAlert>, autoRefill?: IAutoRefill, info?: IPackInfo) {
    const { t } = this.props;
    const extraAlerts = [];

    if (autoRefill && info) {
      extraAlerts.push({
        key:
          autoRefill.triggerType === 'AmountLimit'
            ? t('usage.autoRefillIf')
            : t('usage.autoRefill'),
        value: autoRefill.nextRefill
          ? this.autoRefillAlertValue(autoRefill.nextRefill, autoRefill.triggerType, info.typeId)
          : '',
      });
    }

    const mappedItems = alerts.map((a: IAlert) => ({
      key: a.description,
      value: a.message,
    }));

    return mappedItems.concat(extraAlerts);
  }

  autoRefillAlertValue = (nextRefill: Date, triggerType: string, refillType: string) => {
    const { t } = this.props;

    if (triggerType === 'BeginningOfMonth' && !nextRefill) {
      const date = new Date();

      return distanceToDate(new Date(date.getFullYear(), date.getMonth() + 1, 0), new Date());
    }
    if (triggerType === 'AmountLimit') {
      switch (refillType) {
        case 'Phone':
          return t('usage.below', { unit: '200 kr.' });
        default:
          return t('usage.below', { unit: '200 MB' });
      }
    }
    return distanceToDate(nextRefill, new Date());
  };

  render() {
    const { profile, onSelect, selectedPack, allowEmptyUsage, t, authentication } = this.props;
    const { subscriptionId } = profile;
    const isStaff = authentication?.isStaff;
    const accountInput = authentication?.accountInput;

    return (
      <UsageQuery variables={{ subscriptionId }}>
        {(props) => {
          const { loading, error, data, refetch } = props;

          if (error) {
            return allowEmptyUsage ? null : (
              <EmptyMessage
                title={t('usage.noUsage')}
                description={t('usage.noUsageMessage', { subscription: subscriptionId })}
              >
                <DateSVG />
              </EmptyMessage>
            );
          }

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

          if (!data || !data.me) {
            return allowEmptyUsage ? null : (
              <EmptyMessage
                title={t('usage.noUsage')}
                description={t('usage.noUsageMessage', { subscription: subscriptionId })}
              >
                <DateSVG />
              </EmptyMessage>
            );
          }

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

          if (!profiles[0]) return null;
          const { packs } = profiles[0];

          if (!packs || isEmpty(packs)) {
            return null;
          }

          const { rateplan } = profile;
          const orderedPacks = sortBy(
            packs.map((pack: IUsagePack) => new UsagePack(pack)),
            ['order'],
          );

          return (
            <>
              {orderedPacks.map((pack, i) => {
                const {
                  info,
                  primaryDisplayUsage,
                  alerts,
                  title,
                  isExcessUsage,
                  validTo,
                  connectionId,
                } = pack;

                if (
                  pack.items.length > 0 &&
                  pack.items[0] &&
                  pack.items[0]?._remaining?.amount < 1 &&
                  pack.items[0]?._remaining?.unit?.includes('kr')
                ) {
                  return null;
                }
                let connectionIdFormatted;
                const autoRefill = profile.findAutoRefillForPack(orderedPacks as UsagePack[], i);

                const showValidTime =
                  validTo &&
                  !autoRefill &&
                  ((rateplan.isPrepaid && !isEmpty(info) && info.contentType !== 'rateplan') ||
                    (rateplan.isPrepaid && isEmpty(info)));

                const showPrice = (!rateplan.isPrepaid || !!autoRefill) && !rateplan.isVip;
                const selected = !!selectedPack && parseInt(selectedPack, 10) === i;

                const hasFlutningsfridindi =
                  title.toLowerCase().includes('flutningsfríðindi') ||
                  title.toLowerCase().includes('5g lán');

                const canRemoveDataOrBalance =
                  isStaff &&
                  (!pack.servicepackId ||
                    pack.servicepackId.startsWith('S') ||
                    pack?.servicepackId?.startsWith('Hbalance'));

                if (pack.servicepackId === 'S2103') return;
                if (connectionId) {
                  connectionIdFormatted = formatTel(connectionId as string);
                }
                return (
                  <UsageBoxItem
                    key={`usage-pack-${i}`}
                    color={profileColor(profile.rateplan)}
                    title={info?.title ?? title}
                    content={
                      !hasFlutningsfridindi && (connectionIdFormatted ?? primaryDisplayUsage)
                    }
                    showPrice={showPrice}
                    price={
                      info &&
                      formatPrice(info.price as number, {
                        showZero: true,
                        monthly: !isExcessUsage,
                        unit: info.billingUnit,
                      })
                    }
                    info={info?.remainingSubtitle ?? ''}
                    onClick={!isEmpty(info) ? () => onSelect(i) : undefined}
                    alerts={this.parseAlerts(alerts as IAlert[], autoRefill, info as IPackInfo)}
                    canRemoveDataOrBalance={canRemoveDataOrBalance}
                    validTime={
                      showValidTime && validTo
                        ? t('usage.remaining', {
                            amount: `${distanceToDate(new Date(validTo as string), new Date())}`,
                          })
                        : ''
                    }
                    selected={selected}
                    servicePackId={pack?.servicepackId ?? ''}
                    refetch={refetch}
                    accountInput={accountInput}
                    backupSubscriptionId={subscriptionId}
                  />
                );
              })}
            </>
          );
        }}
      </UsageQuery>
    );
  }
}

export default inject('authentication')(withTranslation('subscription')(observer(Usage)));
