import React, { useState } from 'react';
import { Box, Icon, Input, MainButton, SecondaryButton, 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 { IContext } from 'typings/context';
import {
  useAddDepartmentMutation,
  useChangeDepartmentMutation,
  useDepartmentsQuery,
  useSubscriptionsQuery,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

const COLOR = 'pink';

type DeildProps = {
  hradleid: Hradleid;
  authentication: Authentication;
};

const Deild = ({ hradleid, authentication }: DeildProps) => {
  const { t } = useTranslation(['multi']);
  const { enqueueSnackbar } = useSnackbar();
  const router = useRouter();
  const ssn = router?.query?.ssn ?? '';
  const [checkedSubs, setCheckedSubs] = useState<string[]>();
  const [department, setDepartment] = useState('');
  const [newDepartment, setNewDepartment] = useState('');
  const [addOpen, setAddOpen] = useState(false);
  const { accountInput } = authentication;
  const { data, loading, error, refetch } = useDepartmentsQuery({
    variables: {
      accountInput: {
        ssn: ssn.toString(),
      },
      servicesRequired: false,
    },
  });
  const { data: subData } = useSubscriptionsQuery({
    variables: {
      subscriptionsInput: {
        onlyActive: true,
        forBulkMethods: true,
        perPage: 1000,
      },
      accountInput,
    },
    ssr: false,
  });

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

  const departments = data?.me?.departments;

  const findDepartmentName = (id: string) => {
    const department = departments?.find((dep) => dep.id === id);

    return department?.name;
  };

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

      return {
        name: truncatedName,
        info: departmentName ?? 'Engin Deild',
        id: subscription?.subscriptionId ?? '',
        payer: subscription?.accountSsn ?? '',
      };
    });
  };

  const [connectDepartment, { loading: loadingConnect }] = useChangeDepartmentMutation({});

  const [addDepartment, { loading: loadingAdd }] = useAddDepartmentMutation({
    onCompleted: (data) => {
      enqueueSnackbar(t('multi:department.success'), {
        variant: 'success',
      });
      refetch();
      if (data?.addDepartment?.department?.id) {
        setDepartment(data?.addDepartment?.department?.id);
      }
    },
    onError: (error) => {
      enqueueSnackbar(t('multi:department.fail') + error.message, {
        variant: 'error',
      });
    },
  });

  const onSubmit = async () => {
    try {
      const { data: connectToSubsData } = await connectDepartment({
        variables: {
          input: { newDepartmentId: department, ssn: ssn?.toString(), msisdnList: checkedSubs },
        },
      });
      if (!connectToSubsData) {
        enqueueSnackbar(t('multi:department.fail'), {
          variant: 'error',
        });
      }
      if (connectToSubsData) {
        enqueueSnackbar(t('multi:department.success'), {
          variant: 'success',
        });
        router.push(`/${ssn}/fjoldaskraning`);
        hradleid?.incrementTrigger();
      }
    } catch (error) {
      if (error instanceof Error)
        enqueueSnackbar(t('multi:department.fail') + error.message, {
          variant: 'error',
        });
    }
  };

  const mappedSubs = mapSubsToUsernamesAndInfo();
  const subsWhereCustomerIsNotPayer = mappedSubs?.filter((sub) => sub.payer !== ssn);
  const filteredSubIds = subsWhereCustomerIsNotPayer?.map((sub) => sub.id);
  const getCheckedContracts = (subIds: Array<string>) => {
    setCheckedSubs(subIds);
  };

  const onAddClick = () => {
    setAddOpen(!addOpen);
  };

  const onEstablishClick = async () => {
    if (newDepartment.length < 1) {
      enqueueSnackbar(t('multi:department.addLengthFail'), {
        variant: 'error',
      });
    } else {
      try {
        await addDepartment({
          variables: {
            input: {
              ssn: ssn.toString(),
              departmentName: newDepartment,
            },
          },
        });
      } catch (error) {
        if (error instanceof Error) {
          enqueueSnackbar(t('multi:department.fail') + error.message, {
            variant: 'error',
          });
        }
      }
      setAddOpen(!addOpen);
    }
  };

  return (
    <MultiStepWrapper
      hradleid={hradleid}
      color={COLOR}
      disabledSubIds={filteredSubIds ?? []}
      getMappedSubs={mappedSubs}
      sendCheckedToChild={getCheckedContracts}
      title={t('multi:department.title')}
      firstRowTitle={t('multi:headers.user')}
      secondRowTitle={t('multi:headers.department')}
      icon="transfer"
      customerName={customerName ?? ''}
    >
      <Box display="flex" flexDirection="column" gap={10}>
        <Box>
          <Text color="black100" variant="h4">
            {t('multi:department.choose')}
          </Text>
          <Text color="black100">{t('multi:department.subtitle')}</Text>
        </Box>
        {!addOpen && (
          <Box>
            <Select
              id="title"
              label={t('multi:headers.department')}
              onChange={(e) => {
                setDepartment(e.target.value);
              }}
              isBold={false}
              disabled={false}
              value={department}
            >
              <option value="" disabled selected={department === ''}>
                {t('multi:department.placeholder')}
              </option>
              {departments?.map((dep) => {
                return (
                  <option key={dep.id} selected={dep.id === department} value={dep?.id ?? ''}>
                    {dep?.name}
                  </option>
                );
              })}
            </Select>
          </Box>
        )}
        <Box>
          <SecondaryButton
            onClick={() => onAddClick()}
            isDisabled={loadingAdd}
            icon={addOpen ? 'close' : 'add'}
            text={addOpen ? t('multi:department.close') : t('multi:department.add')}
            colorScheme="pink"
          ></SecondaryButton>
        </Box>
        {addOpen && (
          <>
            <Box marginTop={-10} width={{ sm: '100%', md: '6/12' }}>
              <Text color="black100">{t('multi:department.addInfo')}</Text>
            </Box>
            <Box
              marginTop={-10}
              width={{ sm: '100%', md: '6/12' }}
              display="flex"
              gap={2}
              flexDirection="column"
            >
              <Input
                label={t('multi:department.new')}
                id="department"
                name="department-name"
                onChange={(e) => setNewDepartment(e.target.value)}
                value={newDepartment}
                disabled={loadingAdd}
                isBold={false}
              />
              <MainButton
                onClick={() => onEstablishClick()}
                isDisabled={loadingAdd}
                icon="addCircle"
                text={t('multi:department.create')}
                colorScheme="pink"
              ></MainButton>
            </Box>
          </>
        )}
        {!addOpen && (
          <Box marginTop={10} width="4/12" marginLeft="auto">
            <MainButton
              colorScheme="pink"
              dottedShadow="none"
              text={t('multi:department.confirm')}
              onClick={() => onSubmit()}
              isDisabled={loading || loadingConnect || department === '' || addOpen}
            />
          </Box>
        )}
        {error && (
          <Box alignItems="flex-end" display="flex" flexDirection="row" gap={1} marginTop={-10}>
            <Icon icon="info" color="warning" />
            <Text marginRight="auto" color="warning" variant="pSmallRegular">
              {t('multi:department.error')}
            </Text>
          </Box>
        )}
        {filteredSubIds && filteredSubIds.length > 0 && (
          <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
            <Icon icon="info" color="warning" />
            <Text>{t('multi:department.payerError')}</Text>
          </Box>
        )}
      </Box>
    </MultiStepWrapper>
  );
};

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

export default inject('hradleid', 'authentication')(observer(Deild));
