import React, { useCallback, useEffect, useState } from 'react';

import { SignClientTypes } from '@walletconnect/types';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

import SignMessage from './components/SignMessage';
import HomeScreen from './components/HomeScreen';
import SignRequest from './components/SignRequest';
import InvalidPath from './components/InvalidPath';
import PairingModal from './components/PairingModal';
import SignModal from './components/SignModal';
import WalletConnect from './components/WalletConnect';
import { StackParamsList } from './types';
import useInitialization, {
  web3wallet,
} from './utils/wallet-connect/WalletConnectUtils';
import { EIP155_SIGNING_METHODS } from './utils/wallet-connect/EIP155Lib';
import { retrieveAccounts } from './utils/accounts';

const Stack = createNativeStackNavigator<StackParamsList>();

const App = (): React.JSX.Element => {
  useInitialization();

  const [modalVisible, setModalVisible] = useState(false);
  //TODO: Remove any
  const [currentProposal, setCurrentProposal] = useState<
    SignClientTypes.EventArguments['session_proposal'] | undefined
  >();
  const [requestSession, setRequestSession] = useState<any>();
  const [requestEventData, setRequestEventData] = useState<any>();
  const [signModalVisible, setSignModalVisible] = useState(false);
  const [currentEthAddresses, setCurrentEthAddresses] = useState<string[]>([]);

  const onSessionProposal = useCallback(
    (proposal: SignClientTypes.EventArguments['session_proposal']) => {
      setModalVisible(true);
      setCurrentProposal(proposal);
    },
    [],
  );

  const onSessionRequest = useCallback(
    async (requestEvent: SignClientTypes.EventArguments['session_request']) => {
      const { topic, params } = requestEvent;
      const { request } = params;
      const requestSessionData =
        web3wallet.engine.signClient.session.get(topic);

      switch (request.method) {
        case EIP155_SIGNING_METHODS.ETH_SIGN:
        case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
          setRequestSession(requestSessionData);
          setRequestEventData(requestEvent);
          setSignModalVisible(true);
          return;
      }
    },
    [],
  );
  useEffect(() => {
    web3wallet?.on('session_proposal', onSessionProposal);
    web3wallet?.on('session_request', onSessionRequest);
    //TODO: Investigate dependancies
  });

  useEffect(() => {
    const fetchEthAccounts = async () => {
      const { ethLoadedAccounts } = await retrieveAccounts();

      if (ethLoadedAccounts) {
        const ethAddreses = ethLoadedAccounts.map(account => account.address);
        setCurrentEthAddresses(ethAddreses);
      }
    };

    fetchEthAccounts();
    // TODO: Use context to maintain accounts state
  }, [modalVisible]);

  const linking = {
    prefixes: ['https://www.laconic-wallet.com'],
    config: {
      screens: {
        SignRequest: {
          path: 'sign/:network/:address/:message',
        },
      },
    },
  };

  return (
    <NavigationContainer linking={linking}>
      <Stack.Navigator>
        <Stack.Screen
          name="Laconic"
          component={HomeScreen}
          options={{
            title: 'Laconic Wallet',
            headerBackVisible: false,
          }}
        />
        <Stack.Screen
          name="SignMessage"
          component={SignMessage}
          options={{
            title: 'Sign Message',
          }}
          initialParams={{ selectedNetwork: 'Ethereum' }}
        />
        <Stack.Screen
          name="SignRequest"
          component={SignRequest}
          options={{
            title: 'Sign Message?',
          }}
        />
        <Stack.Screen
          name="InvalidPath"
          component={InvalidPath}
          options={{
            title: 'Bad Request',
            headerBackVisible: false,
          }}
        />
        <Stack.Screen
          name="WalletConnect"
          component={WalletConnect}
          options={{
            title: 'Connect Wallet',
          }}
        />
      </Stack.Navigator>
      <PairingModal
        visible={modalVisible}
        setModalVisible={setModalVisible}
        currentProposal={currentProposal}
        setCurrentProposal={setCurrentProposal}
        currentEthAddresses={currentEthAddresses}
      />

      <SignModal
        visible={signModalVisible}
        setModalVisible={setSignModalVisible}
        requestEvent={requestEventData}
        requestSession={requestSession}
        currentEthAddresses={currentEthAddresses}
      />
    </NavigationContainer>
  );
};

export default App;
