import React, { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { useQuery } from '@apollo/client';
import { ErrorMessage } from '@hookform/error-message';
import {
  Box,
  FormStatusMessage,
  Grid,
  GridItem,
  Icon,
  MainButton,
  Radio,
  Select,
  Text,
} from '@nova-hf/ui';
import { getMaxLengthOfName } from 'beta/utils/helpers';
import MultiStepWrapper from 'containers/multiStepWrapper/MultiStepWrapper';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import { useSnackbar } from 'notistack';
import Authentication from 'store/authentication';
import Hradleid from 'store/hradleid';
import UI from 'store/ui';
import { IContext } from 'typings/context';
import {
  PaymentType_Deprecated,
  useChangeSubscriptionRateplanMutation,
  useSubscriptionsQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

import { CARDS } from '../../../graphql/queries/cards';
import { ALLRATEPLANS } from '../../../graphql/queries/rateplans';
import { IRateplanCategory, IUserData } from '../../../typings';

const COLOR = 'pink';

type ThjonustuleidProps = {
  hradleid: Hradleid;
  authentication: Authentication;
  ui: UI;
};

type mappedSubscription = {
  name: string;
  info: string;
  id: string;
  payer?: string;
};

type ChangeRateplanForm = {
  rateplanId: string;
  paymentType: PaymentType_Deprecated;
  servicepackId?: string;
  activateNextMonth: boolean;
  paymentId?: string;
};

const Thjonustuleid = ({ hradleid, authentication, ui }: ThjonustuleidProps) => {
  const { t } = useTranslation(['multi']);
  const { enqueueSnackbar } = useSnackbar();
  const [checkedSubIds, setCheckedSubIds] = useState<string[]>();
  const [card, setCard] = useState('');
  const [needsPayment, setNeedsPayment] = useState(true);
  const router = useRouter();
  const ssn = router?.query?.ssn;
  const { accountInput } = authentication;
  const { data: cardData } = useQuery<IUserData>(CARDS, { variables: { accountInput } });
  const { data: rateplanData } = useQuery<IRateplanCategory>(ALLRATEPLANS);
  const { data } = useSubscriptionsQuery({
    variables: {
      subscriptionsInput: {
        onlyActive: true,
        forBulkMethods: true,
        perPage: 1000,
      },
      accountInput,
    },
    ssr: false,
  });

  const subscriptions = data?.me?.subscriptions?.subscriptions;
  const customerName = data?.me?.name;

  const mapSubsToUsernamesAndInfo = () => {
    return hradleid?.subscriptionIds?.map((subId) => {
      const subscription = subscriptions?.find((sub) => sub?.subscriptionId === subId);
      const username = subscription?.name;
      const MAX = getMaxLengthOfName();
      const currentRateplanName = subscription?.rateplan?.title;
      const truncatedName =
        username && username.length > MAX ? `${username.slice(0, MAX)}...` : username;

      return {
        name: (truncatedName as string) ?? '',
        info: currentRateplanName ?? '',
        id: subId ?? '',
        payer: subscription?.accountSsn ?? '',
      };
    });
  };

  const mappedSubs = mapSubsToUsernamesAndInfo();
  const subsWhereCustomerIsNotPayer = mappedSubs?.filter((sub) => sub.payer !== ssn);
  const filteredSubIds = subsWhereCustomerIsNotPayer?.map((sub) => sub.id);
  const getCheckedSubs = (subIds: Array<string>) => {
    setCheckedSubIds(subIds);
  };
  const changeRateplanInput = (subscription: mappedSubscription) => {
    const isChecked = checkedSubIds?.some((checkedSub) => checkedSub === subscription?.id);
    if (isChecked) {
      return {
        rateplanId: rateplanId,
        paymentType: paymentType,
        servicePackId: servicepackId,
        activateNextMonth: activateNextMonth,
      };
    }
    return null;
  };

  const [changeRateplan, { loading }] = useChangeSubscriptionRateplanMutation({
    onCompleted: (data) => {
      enqueueSnackbar('Tókst að breyta um þjónustuleið', {
        variant: 'success',
      });

      if (data) {
        router.push(`/${router.query.ssn}/fjoldaskraning`);
        hradleid?.incrementTrigger();
        ui.setHasMultiMenu(false);
      }
    },
    onError(error) {
      enqueueSnackbar('Ekki tókst að breyta um þjonustuleið' + error.message, {
        variant: 'error',
      });
    },
  });

  const onSubmit = async (subscriptions: mappedSubscription[] | undefined) => {
    if (subscriptions) {
      for (const subscription of subscriptions) {
        const useInput = changeRateplanInput(subscription);

        if (rateplanId && paymentType && useInput) {
          await changeRateplan({
            variables: {
              subscriptionId: subscription?.id,
              input: {
                rateplanId: rateplanId,
                paymentType: paymentType,
                ...(servicepackId && { servicepackId }),
                activateNextMonth: activateNextMonth,
                paymentId: paymentType === PaymentType_Deprecated.Card ? card : null,
              },
            },
          });
        }
      }
    }
  };

  const { control, watch, handleSubmit, setValue } = useForm<ChangeRateplanForm>({
    defaultValues: {
      rateplanId: '',
      paymentType: PaymentType_Deprecated.Bank,
      servicepackId: '',
      activateNextMonth: false,
      paymentId: '',
    },
    delayError: 500,
    mode: 'onChange',
  });

  const { rateplanId, paymentType, servicepackId, activateNextMonth } = watch();

  const filteredSubscriptions = subscriptions?.filter(
    (sub) => checkedSubIds?.includes(sub?.subscriptionId),
  );

  const availableRateplans =
    filteredSubscriptions && filteredSubscriptions?.length > 0
      ? filteredSubscriptions[0].rateplan?.availableRateplans?.[0]?.rateplans?.filter((rateplan) =>
          filteredSubscriptions.every(
            (sub) =>
              sub.rateplan?.availableRateplans?.[0]?.rateplans?.some(
                (rp) => rp?.id === rateplan.id,
              ),
          ),
        )
      : [];

  const servicepacks = rateplanData?.rateplans
    .find((r) => r.id === 'R2088')
    ?.availableServicepacks.find((s) => s.servicepackType === 'phonedata');

  useEffect(() => {
    const needsPayment = rateplanData?.rateplans
      .find((r) => r.id === rateplanId)
      ?.title.toLowerCase()
      .includes('frelsi');
    setNeedsPayment(needsPayment ?? true);
  }, [rateplanId]);

  const cards = cardData?.me?.cards;

  return (
    <MultiStepWrapper
      hradleid={hradleid}
      color={COLOR}
      getMappedSubs={mappedSubs}
      disabledSubIds={filteredSubIds ?? []}
      sendCheckedToChild={getCheckedSubs}
      title={t('thjonustubreyting.title')}
      firstRowTitle={t('headers.user')}
      secondRowTitle={t('thjonustubreyting.title')}
      icon="arrowsLeftRight"
      customerName={customerName ?? ''}
    >
      <Box display="flex" flexDirection="column" gap={3}>
        <Text color="black100" variant="h4">
          {t('thjonustubreyting.choose')}
        </Text>
        <Text color="black100">
          Hér að neðan getur þú valið í hvaða þjónustuleið valdar þjónustur eiga að fara í.
        </Text>

        <Box renderAs="form" onSubmit={handleSubmit(() => onSubmit(mappedSubs))}>
          <Grid gridTemplate={{ sm: 4, md: 8 }}>
            <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
              <Controller
                name="rateplanId"
                control={control}
                rules={{
                  required: true,
                }}
                render={({ field, formState: { errors } }) => {
                  const { name } = field;
                  return (
                    <Box>
                      <Select
                        id="rateplan"
                        label="Þjónustuleið"
                        name={name}
                        onChange={(e) => {
                          const selectedRateplan = e.target.value;
                          setValue('rateplanId', selectedRateplan);
                        }}
                        disabled={loading}
                        required
                      >
                        <option value="" hidden>
                          Veldu þjónustuleið
                        </option>
                        {availableRateplans?.map((option, index) => {
                          return (
                            <option hidden={option?.id === ''} key={index} value={option?.id ?? ''}>
                              {option?.title}
                            </option>
                          );
                        })}
                      </Select>
                      <ErrorMessage
                        errors={errors}
                        name={name}
                        render={() => (
                          <FormStatusMessage message={t('discounts.reasonError')} status="error" />
                        )}
                      />
                    </Box>
                  );
                }}
              />
            </GridItem>
            {rateplanId === 'R2088' && (
              <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
                <Controller
                  name="servicepackId"
                  control={control}
                  render={({ field, formState: { errors } }) => {
                    const { name } = field;
                    return (
                      <Box>
                        <Select
                          id="service-pack"
                          label="Netpakki"
                          name={name}
                          onChange={(e) => {
                            const selectedServicepack = e.target.value;
                            setValue('servicepackId', selectedServicepack);
                          }}
                          disabled={loading}
                          required
                        >
                          <option value="" hidden>
                            Veldu Netpakka
                          </option>
                          {servicepacks?.servicepacks?.map((option, index) => {
                            return (
                              <option
                                hidden={option?.id === ''}
                                key={index}
                                value={option?.id ?? ''}
                              >
                                {option?.title}
                              </option>
                            );
                          })}
                        </Select>
                        <ErrorMessage
                          errors={errors}
                          name={name}
                          render={() => (
                            <FormStatusMessage
                              message={t('discounts.reasonError')}
                              status="error"
                            />
                          )}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
            )}
            <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
              <Controller
                name="activateNextMonth"
                control={control}
                render={() => {
                  return (
                    <Box display="flex" flexDirection="row" gap={3}>
                      <Radio
                        isChecked={activateNextMonth}
                        value="Breyting fer fram í næsta mánuði"
                        color={COLOR}
                        onChange={() => setValue('activateNextMonth', true)}
                      />
                      <Radio
                        isChecked={!activateNextMonth}
                        value="Breyting gerist strax"
                        color={COLOR}
                        onChange={() => setValue('activateNextMonth', false)}
                      />
                    </Box>
                  );
                }}
              />
            </GridItem>
            {needsPayment && (
              <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
                <Controller
                  name="paymentType"
                  control={control}
                  render={() => {
                    return (
                      <Box display="flex" flexDirection="row" gap={3}>
                        <Radio
                          isChecked={paymentType === PaymentType_Deprecated.Bank}
                          value="Heimabanki"
                          color={COLOR}
                          onChange={() => setValue('paymentType', PaymentType_Deprecated.Bank)}
                        />
                        <Radio
                          isChecked={paymentType === PaymentType_Deprecated.Card}
                          value="Kort"
                          color={COLOR}
                          onChange={() => setValue('paymentType', PaymentType_Deprecated.Card)}
                        />
                      </Box>
                    );
                  }}
                />
              </GridItem>
            )}
            {needsPayment && paymentType !== PaymentType_Deprecated.Bank && (
              <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
                <Select
                  id="card"
                  label="Kort"
                  onChange={(e) => {
                    const selectedCard = e.target.value;
                    setCard(selectedCard);
                  }}
                  disabled={loading}
                  required
                >
                  <option value="" hidden>
                    Veldu kort
                  </option>
                  {cards?.map((option, index) => {
                    return (
                      <option hidden={option?.id === ''} key={index} value={option?.id ?? ''}>
                        {option?.issuer} -{' '}
                        {option?.maskedNumber?.substring(
                          option?.maskedNumber?.length - 8,
                          option?.maskedNumber?.length,
                        )}
                      </option>
                    );
                  })}
                </Select>
              </GridItem>
            )}
            <GridItem gridColumn={{ sm: 'span4', md: 'span8' }}>
              <Box
                display="flex"
                marginTop={6}
                justifyContent="flex-end"
                flexDirection={{ sm: 'column', md: 'row' }}
              >
                <Box display="flex" width={{ sm: '100%', md: '4/12' }}>
                  <MainButton
                    text={'Breyta'}
                    colorScheme={COLOR}
                    isDisabled={!rateplanId || !paymentType}
                    isSubmitButton
                    isLoading={loading}
                  />
                </Box>
              </Box>
            </GridItem>
          </Grid>
        </Box>
      </Box>
      {filteredSubIds && filteredSubIds.length > 0 && (
        <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
          <Icon icon="info" color="warning" />
          <Text>{t('multi:multi.payerError')}</Text>
        </Box>
      )}
      {!availableRateplans && (
        <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
          <Icon icon="info" color="warning" />
          <Text>Engin þjónustuleið er í boði fyrir allar valdar þjónustur</Text>
        </Box>
      )}
    </MultiStepWrapper>
  );
};

Thjonustuleid.getInitialProps = ({ pathname, query }: IContext) => {
  return {
    pathname,
    customerId: query.ssn,
    namespacesRequired: ['multi'],
  };
};

export default inject('hradleid', 'authentication', 'ui')(observer(Thjonustuleid));
