import React, {FC, useState, useEffect} from 'react';
import * as Sentry from '@sentry/react-native';
import {Severity} from '@sentry/types';
import {Modal} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useNavigation} from '@react-navigation/native';
import {SdkService} from '@services/AffinidiSDKService';
import useUser from '@contexts/user';
import {usePost} from '@hooks/api';
import {issuanceServiceInstance} from '@services/Axios';
import Loader from '@components/Loader';
import Credential from '@components/Credential';
import Checkbox from '@components/Checkbox';
import {CREDENTIAL_DETAIL} from '@constants/navigation/credential-detail';
import {CLAIMABLE, CLAIM_ALL} from '@constants/api';
import {
  IClaimableCredentialProps,
  ClaimableVCType,
} from '@components/Credential/types';
import {
  Overlay,
  Wrapper,
  Footer,
  FooterButton,
  FooterButtonLabelStyle,
  Title,
  SubTitle,
  Body,
  Row,
  Col,
} from '@styles/components/new-credential-modal';
interface IProps {
  later: () => void;
  alreadyLaunched: string | undefined | null;
}

const PREV_READ_NOTIFICATIONS = '@PREV_READ_NOTIFICATIONS';

const parseJwt = (token: string) => {
  const base64Payload = token.split('.')[1];
  const payload = Buffer.from(base64Payload, 'base64');
  return JSON.parse(payload.toString());
};

const DeleteCredentialModal: FC<IProps> = ({later, alreadyLaunched}) => {
  const [visible, setVisible] = useState(false);
  const [claimableCredentials, setClaimableCredentials] = useState<
    IClaimableCredentialProps[]
  >([]);
  const {
    getPassword,
    getEncryptedSeed,
    sdk,
    initiateSdk,
    getPhoneNumber,
    setCredentials,
    user,
    setUser,
  } = useUser();
  const {mutateAsync} = usePost();
  const navigation = useNavigation<any>();
  const [phoneNumber, setPhoneNumber] = useState<string | undefined>(undefined);

  const hide = () => setVisible(false);

  useEffect(() => {
    (async () => {
      const value = await getPhoneNumber();
      if (value) {
        setPhoneNumber(value);
      }
    })();
  }, [getPhoneNumber]);

  useEffect(() => {
    (async () => {
      try {
        if (!sdk) {
          const password = await getPassword();
          const encryptedSeed = await getEncryptedSeed();
          if (password && encryptedSeed) {
            const v = await SdkService.openWalletByEncryptedSeed(
              encryptedSeed,
              password,
            );
            initiateSdk(v);
          }
        }
      } catch (e: any) {
        Sentry.captureMessage(
          `Error from openWalletByEncryptedSeed : ${e?.message}`,
          Severity.Error,
        );
      }
    })();
  }, [getPassword, getEncryptedSeed, initiateSdk, sdk]);

  useEffect(() => {
    let timer = setTimeout(async () => {
      if (!claimableCredentials?.length && phoneNumber) {
        try {
          const response = await issuanceServiceInstance.get(
            `${CLAIMABLE}?userId=${phoneNumber}`,
          );

          if (response?.data?.length) {
            setUser({...user, hasNewNotifications: true});

            const prevReadNotifications = await AsyncStorage.getItem(
              PREV_READ_NOTIFICATIONS,
            );
            let newNotifications = [];

            if (prevReadNotifications) {
              let oldReadNotifications = JSON.parse(prevReadNotifications);

              for (let i = 0; i < response?.data.length; i++) {
                const draftVCId = response?.data[i]?.DraftVCId;
                const exist = oldReadNotifications?.find(
                  (d: IClaimableCredentialProps) => d === draftVCId,
                );

                if (!exist) {
                  newNotifications.push(response?.data[i]);
                  oldReadNotifications.push(response?.data[i]?.DraftVCId);
                }
              }
              await AsyncStorage.setItem(
                PREV_READ_NOTIFICATIONS,
                JSON.stringify(oldReadNotifications),
              );
            } else {
              newNotifications = response?.data;

              await AsyncStorage.setItem(
                PREV_READ_NOTIFICATIONS,
                JSON.stringify(
                  newNotifications?.map(
                    (d: IClaimableCredentialProps) => d?.DraftVCId,
                  ),
                ),
              );
            }

            if (newNotifications?.length) {
              setClaimableCredentials(
                newNotifications?.map((d: IClaimableCredentialProps) => ({
                  ...d,
                  checked: true,
                })),
              );
              setVisible(true);
            }
          }
        } catch (error: any) {
          Sentry.captureMessage(
            `Error while fetching the claimable credentials, Mobile Number : ${phoneNumber}, Error : ${error?.message}`,
          );
          console.error(error);
        }
      }
    }, 5000);

    return () => {
      clearTimeout(timer);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [phoneNumber, claimableCredentials]);

  const selectedClaimableCredentials = claimableCredentials?.filter(
    v => v?.checked,
  );
  const disabled = !selectedClaimableCredentials?.length;

  return (
    <Modal
      animationType="fade"
      transparent={true}
      visible={visible}
      onRequestClose={hide}>
      <Overlay onPress={hide} activeOpacity={1} />

      <Wrapper edges={['bottom']} testID="notifPop">
        <Title>New credential alert!</Title>
        <SubTitle>You have received new credential from learnet</SubTitle>
        <Body>
          {claimableCredentials?.map(
            (credential: IClaimableCredentialProps, i: number) => (
              <Row key={credential?.DraftVCId}>
                <Checkbox
                  checked={!!credential?.checked}
                  onChange={() =>
                    setClaimableCredentials(
                      claimableCredentials?.map(
                        (v: IClaimableCredentialProps, j: number) => ({
                          ...v,
                          checked: i === j ? !v?.checked : v?.checked,
                        }),
                      ),
                    )
                  }
                />
                <Col>
                  <Credential
                    active={true}
                    credential={credential}
                    onPress={async () => {
                      let params = [];

                      if (selectedClaimableCredentials?.length) {
                        for (
                          let j = 0;
                          j < selectedClaimableCredentials.length;
                          j++
                        ) {
                          const element = selectedClaimableCredentials[j];

                          if (element?.CredentialOfferRequestToken) {
                            const value = parseJwt(
                              element?.CredentialOfferRequestToken,
                            );
                            const credentialInfo =
                              value.interactionToken.offeredCredentials[0]
                                .renderInfo.data;

                            params.push({
                              ...credentialInfo,
                              CredentialOfferRequestToken:
                                element?.CredentialOfferRequestToken,
                              DraftVCId: element?.DraftVCId,
                              issuerId: element?.IssuerId,
                              VCName: element?.VCName,
                            });
                          }
                        }
                      } else {
                        if (credential?.CredentialOfferRequestToken) {
                          const value = parseJwt(
                            credential?.CredentialOfferRequestToken,
                          );
                          const credentialInfo =
                            value.interactionToken.offeredCredentials[0]
                              .renderInfo.data;
                          params.push({
                            ...credentialInfo,
                            CredentialOfferRequestToken:
                              credential?.CredentialOfferRequestToken,
                            DraftVCId: credential?.DraftVCId,
                            issuerId: credential?.IssuerId,
                            VCName: credential?.VCName,
                          });
                        }
                      }

                      hide();
                      navigation.navigate({
                        name: CREDENTIAL_DETAIL.SCREEN,
                        params,
                      });
                    }}
                  />
                </Col>
              </Row>
            ),
          )}
        </Body>
        <Footer>
          <FooterButton
            title="Remind me later"
            variant="text"
            onPress={async () => {
              hide();
              if (!alreadyLaunched) {
                later();
              }
            }}
            labelStyles={FooterButtonLabelStyle}
            testID="rmdLtr"
          />
          <FooterButton
            title="Add to wallet"
            labelStyles={FooterButtonLabelStyle}
            disabled={disabled}
            onPress={async () => {
              const checkedClaimableCredentials = claimableCredentials?.filter(
                v => v?.checked,
              );
              let claimablePayload: ClaimableVCType[] = [];
              for (
                let index = 0;
                index < checkedClaimableCredentials.length;
                index++
              ) {
                const element = checkedClaimableCredentials[index];
                const requestToken = element?.CredentialOfferRequestToken;
                if (requestToken) {
                  const offerResponseToken =
                    await sdk?.createCredentialOfferResponseToken(requestToken);
                  const payload = {
                    offerResponseToken,
                    userId: phoneNumber,
                    draftVCId: element?.DraftVCId,
                    issuerId: element?.IssuerId,
                  };
                  claimablePayload.push(payload);
                }
              }
              if (claimablePayload?.length) {
                await mutateAsync({url: CLAIM_ALL, data: claimablePayload});
              }
              setCredentials(undefined);
              setVisible(false);
            }}
            testID="add2Wlt"
          />
        </Footer>
      </Wrapper>

      <Loader />
    </Modal>
  );
};

export default DeleteCredentialModal;
