import React, { useState } from 'react';
import {
  Button,
  ContainerDeprecated,
  NumberTextBox,
  PaymentForm,
  StepTitle,
  SubscriptionButton,
  SubscriptionButtonWrapper,
} from '@nova-hf/ui';
import { Error } from 'components/error/Error';
import { NOVA_SUBSCRIPTION } from 'graphql/queries/novaSubscription';
import { isEmpty, uniqBy } from 'lodash';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import Authentication from 'store/authentication';
import Change from 'store/change';
import { IConnection, IProfile } from 'typings';
import {
  useConnectionsQuery,
  useCustomerIdByNationalIdQuery,
  useFiberServicesContractInfoQuery,
} from 'typings/graphql';
import { formatFirstName, profileColor } from 'utils/helpers';
import { WithTranslation, withTranslation } from 'utils/i18n';

interface IAddConnectionProps extends WithTranslation {
  authentication?: Authentication;
  change?: Change;
  color: string;
  onNext(): void;
  subscriptionId: string;
  types: Array<string>;
  returnLink: any;
}

const AddConnection = ({
  authentication,
  change,
  color,
  onNext,
  subscriptionId,
  types,
  t,
}: IAddConnectionProps) => {
  const [status, setStatus] = useState('');
  const [message, setMessage] = useState('');
  const [msisdn, setMsisdn] = useState('');

  const forms: any = [];
  const router = useRouter();

  const { loading, error, data, client } = useConnectionsQuery({
    variables: { subscriptionId, accountInput: authentication?.accountInput },
  });

  const { data: contractCustomerData } = useCustomerIdByNationalIdQuery({
    variables: {
      input: {
        nationalId: router?.query?.ssn?.toString() ?? '',
      },
    },
    skip: !router?.query?.ssn,
  });

  const customerId = contractCustomerData?.customerByNationalId?.id;

  const { data: contractFiberData } = useFiberServicesContractInfoQuery({
    variables: {
      input: {
        customerId: customerId,
      },
    },
    skip: !customerId,
  });

  const fiberContracts = contractFiberData?.contracts?.contracts
    ?.map((contract) => {
      const hasContractItems = contract.contractItems && contract.contractItems.length > 0;
      const isPayer = contract?.payerId === customerId;

      if (hasContractItems && isPayer) {
        const fiberServices = contract.contractItems
          .filter(
            (item) =>
              item?.__typename === 'ServiceContractItem' &&
              item?.service?.__typename === 'FiberService' &&
              item?.status !== 'Inactive' &&
              !item?.variantId?.includes('ljos-otakmarkad-2500'),
          )
          .map((item) => ({
            address:
              item?.__typename === 'ServiceContractItem' &&
              item?.service?.__typename === 'FiberService'
                ? item?.service?.propertyDescription
                : '',
            serviceId:
              item?.__typename === 'ServiceContractItem' &&
              item?.service?.__typename === 'FiberService'
                ? item?.serviceId
                : '',
            username:
              item?.__typename === 'ServiceContractItem' &&
              item?.service?.__typename === 'FiberService'
                ? item?.service?.user?.name
                : '',
          }));

        return fiberServices;
      }

      return null;
    })
    .filter(Boolean);

  const flattenFiberContracts = fiberContracts?.flat();
  const uniqFiberServices = uniqBy(flattenFiberContracts, 'serviceId');

  if (error) {
    return null;
  }

  if (loading) {
    return <div>Sæki upplýsingar...</div>;
  }

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

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

  const selections = (
    subscriptions: Array<IProfile> | any,
    connections: Array<IConnection> | any,
  ) => {
    return subscriptions?.filter(
      ({ subscriptionId, rateplan: { typeId } }: IProfile) =>
        types.includes(typeId) &&
        connections &&
        !connections.find((c: { subscriptionId: string }) => c.subscriptionId === subscriptionId),
    );
  };

  const onClick = (subscription: IProfile) => {
    change?.changeConnection(subscription?.subscriptionId ?? msisdn);
    onNext();
  };

  const betaOnClick = (serviceId: string) => {
    change?.changeConnection(serviceId);
    onNext();
  };

  const onChangeMsisdn = async (
    e: any,
    client: any,
    connections: Array<IConnection> | any,
    subscriptionTitle: string | undefined | null,
  ) => {
    const msisdn = e.target.value;

    setStatus('');
    setMessage('');
    setMsisdn('');

    if (msisdn.length === 7) {
      const isConnected = !isEmpty(connections)
        ? connections?.find((c: { subscriptionId: any }) => c.subscriptionId === msisdn)
        : false;

      if (isConnected) {
        setStatus('warning');
        setMessage(t('steps.connection.addConnection.mobile.error.alreadyExists'));
      } else {
        try {
          await client.query({
            query: NOVA_SUBSCRIPTION,
            variables: { input: { subscriptionId: msisdn } },
          });

          setStatus('success');
          setMessage('');
          setMsisdn(msisdn);
        } catch {
          setStatus('error');
          setMessage(
            authentication?.isStaff
              ? t('steps.connection.addConnection.mobile.error.notNovaNumber')
              : t('steps.connection.addConnection.mobile.error.somethingWrong', {
                  subscriptionTitle,
                }),
          );
        }
      }
    }
  };

  const currentSubscription = subscriptions?.find(
    (item: { subscriptionId: string }) => item.subscriptionId === subscriptionId,
  );
  const subscriptionTitle = currentSubscription && currentSubscription.title;

  if (!profiles || !profiles[0] || !subscriptions) {
    return (
      <Error
        color={color}
        title={t('steps.initial.errorHeading')}
        description={t('steps.initial.errorDescription')}
      />
    );
  }

  const { connections } = profiles[0];
  const subscriptionsSelections = selections(subscriptions, connections);

  return (
    <ContainerDeprecated>
      <StepTitle
        title={t(`steps.connection.addConnection.${types[0]}.heading`)}
        subtitle={t(`steps.connection.addConnection.${types[0]}.description`, {
          subscriptionTitle,
        })}
        color={color}
      />
      {types[0] === 'mobile' && (
        <PaymentForm ref={(el: any) => (forms[1] = el)}>
          <NumberTextBox
            name="msisdn"
            label={t('steps.connection.addConnection.mobile.label')}
            autoComplete="false"
            errorType="msisdn"
            status={status}
            message={message}
            msisdn
            required
            length={7}
            onChange={(e: any) => {
              onChangeMsisdn(e, client, connections, subscriptionTitle);
            }}
          />
          <Button
            fill
            big
            background={color}
            onClick={onClick}
            loading={false}
            disabled={status !== 'success'}
            arrowRight
          >
            {t('steps.connection.addConnection.mobile.button')}
          </Button>
        </PaymentForm>
      )}
      <SubscriptionButtonWrapper title={t('steps.connection.addConnection.mobile.yournumbers')}>
        {subscriptionsSelections?.map((c: IProfile) => {
          const lines = [`${c.rateplan.title} - ${c.title}`];

          if (c.accountSsn !== c.ssn) {
            lines.push(`Greiðandi: ${c.accountSsn}`);
          }

          return (
            <SubscriptionButton
              key={c.subscriptionId}
              title={formatFirstName(c.name)}
              lines={lines}
              onClick={() => onClick(c)}
              color={profileColor(c.rateplan)}
              fill
              icon={
                c.rateplan.typeId === 'fiber'
                  ? 'wifihouse'
                  : c.rateplan.typeId === 'internet'
                  ? 'net'
                  : 'phone'
              }
            />
          );
        })}
        {uniqFiberServices?.map((service) => {
          const lines = [`${service?.address}`];
          return (
            <SubscriptionButton
              key={service?.serviceId}
              title={formatFirstName(service?.username ?? '')}
              lines={lines}
              onClick={() => betaOnClick(service?.serviceId ?? '')}
              color="purple"
              fill
              icon="net"
            />
          );
        })}
      </SubscriptionButtonWrapper>
    </ContainerDeprecated>
  );
};

export default inject(
  'change',
  'authentication',
)(observer(withTranslation('change')(AddConnection)));
