import React, { useEffect, useState } from 'react';
import { Box, Icon, Input, MainButton, makeToast, NumberInput, Text } from '@nova-hf/ui';
import Hradleid from 'beta/store/hradleid';
import { formatPrice, getMaxLengthOfName } from 'beta/utils/helpers';
import { useTranslation } from 'beta/utils/i18n';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import { IContext } from 'typings/context';
import {
  ContractItemType,
  PaymentCategory,
  useAddExtraPayersMutation,
  useDeleteExtraPayersMutation,
} from 'typings/graphql';

import MultiStepWrapper from '../../../containers/layout/MultiStepWrapper';

const COLOR = 'pink';

type ThakProps = {
  hradleid: Hradleid;
};

type mappedContract = {
  name: string;
  info: string;
  id: string;
  userId: string;
  extraPayerId?: string;
};

const Thak = ({ hradleid }: ThakProps) => {
  const { t } = useTranslation(['multi']);
  const [checkedContracts, setCheckedContracts] = useState<string[]>();
  const [ceiling, setCeiling] = useState('');
  const [toLowError, setToLowError] = useState(false);
  const [highError, setHighError] = useState(false);
  const router = useRouter();
  const customerId = router?.query?.customerId;

  const mapContractsToUsernamesAndInfo = () => {
    return hradleid?.contracts?.map((contract) => {
      const serviceContractItem = contract?.contractItems.find(
        (item) => item.type === ContractItemType.Service,
      );
      const username = serviceContractItem
        ? serviceContractItem?.serviceInfo?.userName
        : t('multi.noName');
      const extraPayerWithCeiling = contract?.extraPayers?.find(
        (item) => item?.amount && item?.amount > 0 && item?.status === 'Active',
      );
      const ceiling = extraPayerWithCeiling?.amount ?? 0;
      const extraPayerId = extraPayerWithCeiling?.id;
      const MAX = getMaxLengthOfName();
      const truncatedName =
        username && username.length > MAX ? `${username.slice(0, MAX)}...` : username;

      return {
        name: truncatedName as string,
        info: formatPrice(ceiling),
        id: contract?.id,
        userId: serviceContractItem?.serviceInfo?.userId,
        extraPayerId: extraPayerId,
        payer: contract?.paymentMethod?.customerId,
      };
    });
  };

  const mappedContracts = mapContractsToUsernamesAndInfo();
  const contractsWhereCustomerIsNotPayer = mappedContracts?.filter(
    (contract) => contract.payer !== customerId,
  );
  const filteredContractIds = contractsWhereCustomerIsNotPayer?.map((contract) => contract.id);
  const getCheckedContracts = (contractIds: Array<string>) => {
    setCheckedContracts(contractIds);
  };
  const extraPayerInput = (contract: mappedContract) => {
    const isChecked = checkedContracts?.some((checkedContract) => checkedContract === contract?.id);
    if (isChecked) {
      return {
        contractId: contract?.id,
        amount: parseInt(ceiling, 10),
        customerId: contract?.userId,
        paymentCategory: PaymentCategory.PaysForExcess,
      };
    }
    return null;
  };

  const deleteInput = (contract: mappedContract) => {
    const isChecked = checkedContracts?.some((checkedContract) => checkedContract === contract?.id);
    if (isChecked) {
      return contract?.extraPayerId;
    }
    return null;
  };

  const extraPayers = mappedContracts?.map(extraPayerInput).filter(Boolean);
  const extraPayerIds = mappedContracts?.map(deleteInput).filter(Boolean);

  const [addCeiling, { loading }] = useAddExtraPayersMutation({
    onCompleted: (data) => {
      makeToast.success(t('ceiling.success'), '');

      if (data) {
        router.push(`/beta/${router.query.customerId}/thjonustur`);
        hradleid?.incrementTrigger();
      }
    },
    onError(error) {
      makeToast.danger(t('ceiling.fail'), error.message);
    },
  });

  const [deleteCeiling, { loading: deleteLoading }] = useDeleteExtraPayersMutation({
    onCompleted: (data) => {
      makeToast.success(t('multi:ceiling.removeMultiSuccess'), '');

      if (data) {
        router.push(`/beta/${router.query.customerId}/thjonustur`);
        hradleid?.incrementTrigger();
      }
    },
    onError(error) {
      makeToast.danger(t('multi:ceiling.removeMultiFail'), error.message);
    },
  });

  const handleButtonClick = async () => {
    if (ceiling && extraPayers) {
      await addCeiling({
        variables: {
          input: {
            extraPayers: extraPayers,
          },
        },
      });
    }
  };

  const handleDeleteClick = async () => {
    if (!ceiling && extraPayerIds) {
      await deleteCeiling({
        variables: {
          input: {
            extraPayerIds: extraPayerIds,
          },
        },
      });
    }
  };

  useEffect(() => {
    if (ceiling) {
      const high = 1000000;
      const numberValue = parseInt(ceiling, 10);
      if (numberValue < 500) setToLowError(true);
      if (numberValue > 499) setToLowError(false);
      if (numberValue > high) setHighError(true);
      if (numberValue < high) setHighError(false);
    }
  }, [ceiling]);

  const placeholderText = hradleid.getCeilingOrMixed();

  return (
    <MultiStepWrapper
      hradleid={hradleid}
      color={COLOR}
      getMappedContracts={mappedContracts}
      disabledContracts={filteredContractIds ?? []}
      sendCheckedToChild={getCheckedContracts}
      title={t('ceiling.ceiling')}
      firstRowTitle={t('headers.user')}
      secondRowTitle={t('ceiling.ceiling')}
      icon="wallet"
    >
      <Box display="flex" flexDirection="column" gap={3}>
        <Text color="black100" variant="h4">
          {t('ceiling.choose')}
        </Text>
        <Text color="black100">{t('ceiling.subtitle')}</Text>

        <Box marginTop={15} display="flex" flexDirection="column" gap={4}>
          <Input
            id="CurrentCeilingInput"
            label={t('ceiling.oldCeiling')}
            value={placeholderText}
            name={t('ceiling.currentCeiling')}
            type="text"
            isBold={false}
            disabled={true}
          />
          <NumberInput
            id="CreditCardInput"
            label={t('ceiling.newCeiling')}
            name="New ceiling Input"
            numberType="number"
            value={ceiling}
            required
            disabled={false}
            onChange={(value) => setCeiling(value)}
          />
        </Box>
        {(toLowError || highError) && (
          <Box
            gap={1}
            display="flex"
            flexDirection="row"
            alignItems="center"
            marginRight="auto"
            width="4/12"
          >
            {toLowError && (
              <>
                <Icon icon="info" color="warning" />
                <Text marginRight="auto" color="warning" variant="pSmallRegular">
                  {t('ceiling.toLowError')}
                </Text>
              </>
            )}
            {highError && (
              <>
                <Icon icon="info" color="warning" />
                <Text marginRight="auto" color="warning" variant="pSmallRegular">
                  {t('ceiling.valueError')}
                </Text>
              </>
            )}
          </Box>
        )}
        <Box
          display="flex"
          flexDirection="row-reverse"
          alignItems="center"
          justifyContent="space-between"
          marginTop={10}
        >
          <Box width="4/12">
            <MainButton
              text={t('ceiling.confirm')}
              onClick={handleButtonClick}
              dottedShadow="none"
              color="pink"
              isLoading={loading}
              isDisabled={!ceiling || toLowError || highError}
            />
          </Box>
          <Box width="4/12">
            <MainButton
              text={t('ceiling.removeCeilings')}
              onClick={handleDeleteClick}
              dottedShadow="none"
              colorScheme="warning"
              isLoading={loading || deleteLoading}
              isDisabled={!extraPayerIds || !!ceiling}
            />
          </Box>
        </Box>
        {filteredContractIds && filteredContractIds.length > 0 && (
          <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
            <Icon icon="info" color="warning" />
            <Text>{t('multi:multi.payerError')}</Text>
          </Box>
        )}
      </Box>
    </MultiStepWrapper>
  );
};

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

export default inject('hradleid')(observer(Thak));
