import { useCallback, useEffect, useState } from 'react';
import { generateNonce, SiweMessage } from 'siwe';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';

import { Box, Modal } from '@mui/material';

import { BASE_URL, VITE_WALLET_IFRAME_URL } from 'utils/constants';

const axiosInstance = axios.create({
  baseURL: BASE_URL,
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*',
  },
  withCredentials: true,
});

const AutoSignInIFrameModal = () => {
  const navigate = useNavigate();

  const [accountAddress, setAccountAddress] = useState();

  useEffect(() => {
    const handleSignInResponse = async (event: MessageEvent) => {
      if (event.origin !== VITE_WALLET_IFRAME_URL) return;

      if (event.data.type === 'SIGN_IN_RESPONSE') {
        try {
          const { success } = (
            await axiosInstance.post('/auth/validate', {
              message: event.data.data.message,
              signature: event.data.data.signature,
            })
          ).data;

          if (success === true) {
            navigate('/');
          }
        } catch (error) {
          console.error('Error signing in:', error);
        }
      }
    };

    window.addEventListener('message', handleSignInResponse);

    return () => {
      window.removeEventListener('message', handleSignInResponse);
    };
  }, []);

  useEffect(() => {
    const initiateAutoSignIn = async () => {
      if (!accountAddress) return;

      const iframe = document.getElementById(
        'autoSignInFrame',
      ) as HTMLIFrameElement;

      if (!iframe.contentWindow) {
        console.error('Iframe not found or not loaded');
        return;
      }

      const message = new SiweMessage({
        version: '1',
        domain: window.location.host,
        uri: window.location.origin,
        chainId: 1,
        address: accountAddress,
        nonce: generateNonce(),
        // Human-readable ASCII assertion that the user will sign, and it must not contain `\n`.
        statement: 'Sign in With Ethereum.',
      }).prepareMessage();

      iframe.contentWindow.postMessage(
        {
          type: 'AUTO_SIGN_IN',
          chainId: '1',
          message,
        },
        VITE_WALLET_IFRAME_URL,
      );
    };

    initiateAutoSignIn();
  }, [accountAddress]);

  useEffect(() => {
    const handleAccountsDataResponse = async (event: MessageEvent) => {
      if (event.origin !== VITE_WALLET_IFRAME_URL) return;

      if (event.data.type === 'WALLET_ACCOUNTS_DATA') {
        setAccountAddress(event.data.data[0].address);
      }
    };

    window.addEventListener('message', handleAccountsDataResponse);

    return () => {
      window.removeEventListener('message', handleAccountsDataResponse);
    };
  }, []);

  const getAddressFromWallet = useCallback(() => {
    const iframe = document.getElementById(
      'autoSignInFrame',
    ) as HTMLIFrameElement;

    if (!iframe.contentWindow) {
      console.error('Iframe not found or not loaded');
      return;
    }

    iframe.contentWindow.postMessage(
      {
        type: 'REQUEST_CREATE_OR_GET_ACCOUNTS',
        chainId: '1',
      },
      VITE_WALLET_IFRAME_URL,
    );
  }, []);

  return (
    <Modal open={true} disableEscapeKeyDown keepMounted>
      <Box
        sx={{
          position: 'absolute',
          top: '50%',
          left: '50%',
          transform: 'translate(-50%, -50%)',
          width: '90%',
          maxWidth: '1200px',
          height: '600px',
          maxHeight: '80vh',
          overflow: 'auto',
          outline: 'none',
        }}
      >
        <iframe
          onLoad={getAddressFromWallet}
          id="autoSignInFrame"
          src={`${VITE_WALLET_IFRAME_URL}/auto-sign-in`}
          width="100%"
          height="100%"
          sandbox="allow-scripts allow-same-origin"
        ></iframe>
      </Box>
    </Modal>
  );
};

export default AutoSignInIFrameModal;
