import React, { useEffect, useState } from 'react';
import {
  Box,
  Checkbox,
  Icon,
  Input,
  MainButton,
  makeToast,
  Modal,
  NotificationBanner,
  Radio,
  Select,
  Text,
} from '@nova-hf/ui';
import Hradleid from 'beta/store/hradleid';
import { 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 {
  Contract,
  ContractItemType,
  useContractsAvailableVariantsQuery,
  useContractsVariantApplicabilityQuery,
  VariantApplicability,
  WhenToApply,
} from 'typings/graphql';

import MultiStepWrapper from '../../../containers/layout/MultiStepWrapper';
import useCompleteMultiOrder from '../[serviceId]/skref/hooks/useCompleteMultiOrder';

const COLOR = 'pink';

type ThjonustuleidabreytingProps = {
  hradleid: Hradleid;
};

const Thjonustuleidabreyting = ({ hradleid }: ThjonustuleidabreytingProps) => {
  const { t } = useTranslation(['multi', 'thjonustubreyting']);
  const router = useRouter();
  const customerId = router?.query?.customerId;
  const [checkedContracts, setCheckedContracts] = useState<string[]>();
  const [disabledContracts, setDisabledContracts] = useState<string[]>();
  const [cantChangeUntilNextMonth, setCantChangeUntilNextMonth] = useState<Contract[]>([]);
  const [errors, setErrors] = useState<string[]>();
  const [imidError, setImidError] = useState('');
  const [variantId, setVariantId] = useState('');
  const [imidiateChosen, setImidiateChosen] = useState(true);

  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:multi.noName');
      const packInfo = contract?.variant?.name ? contract?.variant?.name : t('multi:payer.unknown');
      const MAX = getMaxLengthOfName();
      const truncatedName =
        username && username.length > MAX ? `${username.slice(0, MAX)}...` : username;

      return {
        name: truncatedName as string,
        info: packInfo,
        id: contract?.id,
        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 { data, loading } = useContractsAvailableVariantsQuery({
    variables: {
      input: {
        contractIds: checkedContracts,
      },
    },
  });

  const disabledInputValue = hradleid.getVariantOrMixed();

  const variants = data?.contractsAvailableVariants;

  const options = variants ? [...variants] : [];

  const { data: applicabilityData, loading: applicabilityLoading } =
    useContractsVariantApplicabilityQuery({
      variables: {
        input: {
          contractIds: checkedContracts,
          variantId: variantId,
        },
      },
      skip: !variantId || !checkedContracts,
    });

  useEffect(() => {
    applicabilityData?.contractsVariantApplicability?.map((contract: VariantApplicability) => {
      if (contract?.hasUsedMoreThanIncluded) {
        setDisabledContracts((prevContractIds) => [
          ...(prevContractIds ?? []),
          contract?.contractId,
        ]);
        setErrors((prevErrors) => [
          ...(prevErrors ?? []),
          `Error for contract ${contract?.contractId}: hasUsedMoreThanIncluded is true.`,
        ]);
      }
      if (contract?.isCurrent) {
        setDisabledContracts((prevContractIds) => [
          ...(prevContractIds ?? []),
          contract?.contractId,
        ]);
        setErrors((prevErrors) => [
          ...(prevErrors ?? []),
          `Error for contract ${contract?.contractId}: isCurrent is true.`,
        ]);
      }
      if (contract?.isApplicable && !contract.isApplicableImmediately && imidiateChosen) {
        const matchingContract = hradleid?.contracts?.find(
          (item) => item.id === contract.contractId,
        );
        if (matchingContract) {
          setCantChangeUntilNextMonth((prevContracts) => [
            ...(prevContracts ?? []),
            matchingContract,
          ]);
        }
        setImidError(
          `Error for contract ${contract?.contractId}: isApplicableImmediately is false.`,
        );
      }
      if (contract?.isApplicable && !contract.isApplicableImmediately && !imidiateChosen) {
        setCantChangeUntilNextMonth(
          (prevContractIds) => prevContractIds?.filter((item) => item.id !== contract?.contractId),
        );
        setImidError('');
      }
      if (!contract?.isCurrent && !contract?.hasUsedMoreThanIncluded) {
        setDisabledContracts(
          (prevContractIds) => prevContractIds?.filter((id) => id !== contract?.contractId),
        );
        setErrors(
          (prevErrors) =>
            prevErrors?.filter(
              (error) => !error.includes(`Error for contract ${contract?.contractId}`),
            ),
        );
      }
    });
  }, [applicabilityData]);

  const cantChangeUntilNextMonthIds = cantChangeUntilNextMonth.map((contract) => contract.id);

  const allDisabledContracts = [
    ...(disabledContracts ?? []),
    ...(cantChangeUntilNextMonthIds ?? []),
    ...(filteredContractIds ?? []),
  ];

  const {
    onSubmit,
    orderComplete,
    creatOrderLoading,
    addCartItemsLoading,
    orderError,
    addToCartError,
  } = useCompleteMultiOrder(
    imidiateChosen ? WhenToApply.Immediate : WhenToApply.StartOfNextCycle,
    checkedContracts?.filter((item) => !allDisabledContracts?.includes(item)) ?? [],
    customerId?.toString() ?? '',
    variantId,
  );

  const {
    onSubmit: modalOnSubmit,
    orderComplete: modalOrderComplete,
    creatOrderLoading: modalCreateOrderLoading,
    addCartItemsLoading: modalAddCartItemsLoading,
    orderError: modalOrderError,
    addToCartError: modalAddToCartError,
  } = useCompleteMultiOrder(
    WhenToApply.StartOfNextCycle,
    cantChangeUntilNextMonthIds ?? [],
    customerId?.toString() ?? '',
    variantId,
  );

  useEffect(() => {
    if (orderComplete) {
      makeToast.success(
        t('thjonustubreyting:toast.orderSuccessfulTitle'),
        t('thjonustubreyting:toast.orderSuccessfulDescription'),
      );
      router.push({
        pathname: '/beta/[customerId]/thjonustur',
        query: { customerId: customerId },
      });
      hradleid?.incrementTrigger();
    }
  }, [orderComplete]);

  useEffect(() => {
    if (modalOrderComplete) {
      makeToast.success(
        t('thjonustubreyting:toast.orderSuccessfulTitle'),
        t('thjonustubreyting:toast.orderSuccessfulDescription'),
      );
      setCantChangeUntilNextMonth([]);
      setImidError('');
    }
  }, [modalOrderComplete]);

  useEffect(() => {
    if (orderError)
      makeToast.danger(t('thjonustubreyting:toast.createOrderError'), orderError.message ?? '');
    if (addToCartError)
      makeToast.danger(t('thjonustubreyting:toast.addingCartError'), addToCartError.message ?? '');
    if (modalOrderError)
      makeToast.danger(
        t('thjonustubreyting:toast.createOrderError'),
        modalOrderError.message ?? '',
      );
    if (modalAddToCartError)
      makeToast.danger(
        t('thjonustubreyting:toast.addingCartError'),
        modalAddToCartError.message ?? '',
      );
  }, [orderError, addToCartError]);

  return (
    <MultiStepWrapper
      hradleid={hradleid}
      color={COLOR}
      getMappedContracts={mappedContracts}
      sendCheckedToChild={getCheckedContracts}
      title={t('multi:thjonustubreyting.title')}
      firstRowTitle={t('multi:headers.user')}
      secondRowTitle={t('multi:thjonustubreyting.subtitle')}
      icon="novaLogo"
      disabledContracts={allDisabledContracts ?? []}
    >
      <>
        <Box display="flex" flexDirection="column" gap={3}>
          <Text color="black100" variant="h4">
            {t('multi:thjonustubreyting.choose')}
          </Text>
          <Text color="black100">{t('multi:thjonustubreyting.message')}</Text>
        </Box>
        <Box marginTop={10} display="flex" flexDirection="column" gap={4}>
          <Input
            id="CurrentPackInput"
            label={t('multi:thjonustubreyting.title')}
            value={disabledInputValue}
            name="CurrentPack"
            type="text"
            isBold={false}
            disabled={true}
          />
          <Select
            id="title"
            label={t('multi:thjonustubreyting.new')}
            onChange={(e) => {
              setVariantId(e.target.value);
            }}
            isBold={false}
            disabled={false}
          >
            <option value="" disabled selected>
              {t('multi:thjonustubreyting.extraOption')}
            </option>
            {options.map((option, index) => {
              return (
                <option hidden={option?.id === ''} key={index} value={option?.id ?? ''}>
                  {option?.name}
                </option>
              );
            })}
          </Select>
          {!variants && mappedContracts?.length && (
            <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
              <Icon icon="info" color="warning" />
              <Text color="warning">{t('multi:thjonustubreyting.variantError')}</Text>
            </Box>
          )}
          <Box>
            <Text variant="pMediumBold">{t('multi:thjonustubreyting.when')}</Text>
          </Box>
          <Box display="flex" gap={2}>
            <Radio
              isChecked={imidiateChosen}
              value={t('multi:thjonustubreyting.today')}
              color={COLOR}
              onChange={() => setImidiateChosen(true)}
            />
            <Radio
              isChecked={!imidiateChosen}
              value={t('multi:thjonustubreyting.nextMonth')}
              color={COLOR}
              onChange={() => setImidiateChosen(false)}
            />
          </Box>
        </Box>
        <Box marginTop={5} display="flex" flexDirection="row" justifyContent="space-between">
          {filteredContractIds && filteredContractIds.length > 0 && (
            <Box display="flex" flexDirection="row" alignItems="center" gap={1}>
              <Icon icon="info" color="warning" />
              <Text color="warning">{t('multi:multi.payerError')}</Text>
            </Box>
          )}
          <Box width="6/12" display="flex" flexDirection="column" gap={1}>
            {errors?.some((error) => error.includes('isCurrent')) && (
              <Box display="flex" gap={1} flexDirection="row" alignItems="center">
                <Icon icon="info" color="warning" />
                <Text color="warning">{t('multi:thjonustubreyting.isCurrentError')}</Text>
              </Box>
            )}
            {errors?.some((error) => error.includes('hasUsedMoreThanIncluded')) && (
              <Box display="flex" gap={1} flexDirection="row" alignItems="center">
                <Icon icon="info" color="warning" />
                <Text color="warning">{t('multi:thjonustubreyting.hasUsedMoreThanIncluded')}</Text>
              </Box>
            )}
            {imidError &&
              imidError.length > 1 &&
              cantChangeUntilNextMonth &&
              cantChangeUntilNextMonth.length > 0 && (
                <Modal
                  ariaLabel={t('multi:thjonustubreyting.modal.label')}
                  isVisible={!imidError}
                  onVisibilityChange={(isVisible: boolean) =>
                    isVisible ? setImidError('') : setImidError(imidError)
                  }
                >
                  <NotificationBanner
                    eyebrowText={t('multi:thjonustubreyting.modal.eyebrow')}
                    title={t('multi:thjonustubreyting.modal.title')}
                    hasPingAlert={true}
                    description={t('multi:thjonustubreyting.modal.description')}
                    icon="internet"
                    mainButtonColored={{
                      text: t('multi:thjonustubreyting.modal.confirmButtonText'),
                      icon: 'longArrowRight',
                      onClick: () => modalOnSubmit(),
                      isLoading:
                        loading ||
                        modalAddCartItemsLoading ||
                        modalCreateOrderLoading ||
                        applicabilityLoading,
                      openInNewTab: true,
                    }}
                    mainButtonWhite={{
                      text: t('multi:thjonustubreyting.modal.cancelButtonText'),
                      icon: 'longArrowRight',
                      onClick: () => setImidError(''),
                      openInNewTab: true,
                    }}
                  >
                    <Box display="flex" flexDirection="column" width="100%">
                      {cantChangeUntilNextMonth.map((contract) => {
                        const serviceContractItem = contract?.contractItems.find(
                          (item) => item.type === ContractItemType.Service,
                        );
                        const username = serviceContractItem
                          ? serviceContractItem?.serviceInfo?.userName
                          : t('multi:multi.noName');
                        return (
                          <Box
                            display="flex"
                            flexDirection="row"
                            alignItems="center"
                            key={contract?.id}
                            marginTop={-1}
                          >
                            <Checkbox type="checked" isChecked={true} color="pink" />
                            <Text>{username}</Text>
                          </Box>
                        );
                      })}
                    </Box>
                  </NotificationBanner>
                </Modal>
              )}
          </Box>
          <Box marginBottom={2} width="4/12" marginLeft="auto">
            <MainButton
              text={t('multi:thjonustubreyting.confirm')}
              onClick={() => onSubmit()}
              colorScheme="pink"
              dottedShadow="none"
              isDisabled={!variantId}
              isLoading={
                loading || addCartItemsLoading || creatOrderLoading || applicabilityLoading
              }
            />
          </Box>
        </Box>
      </>
    </MultiStepWrapper>
  );
};

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

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