import { useShuttle } from '@delphi-labs/shuttle-react'
import Image from 'next/image'
import React, { useEffect, useState } from 'react'
import QRCode from 'react-qr-code'

import Button from 'components/Button'
import FullOverlayContent from 'components/FullOverlayContent'
import { ChevronLeft, ChevronRight } from 'components/Icons'
import Text from 'components/Text'
import WalletConnecting from 'components/Wallet/WalletConnecting'
import { CHAINS } from 'constants/chains'
import { ENV } from 'constants/env'
import { WALLETS } from 'constants/wallets'
import useStore from 'store'
import { WalletID } from 'types/enums/wallet'
import { isAndroid, isIOS, isMobile } from 'utils/mobile'

interface Props {
  error?: ErrorObject
}

interface ErrorObject {
  title: string
  message: string
}

interface WalletOptionProps {
  name: string
  imageSrc: string
  handleClick: () => void
}

const currentChainId = ENV.CHAIN_ID
const currentChain = CHAINS[currentChainId]

function WalletOption(props: WalletOptionProps) {
  return (
    <Button
      color='tertiary'
      className='flex w-full !justify-start px-4 py-3'
      onClick={props.handleClick}
    >
      <Image
        className='rounded-full'
        width={20}
        height={20}
        src={props.imageSrc}
        alt={props.name}
      />
      <Text className='ml-2 flex-1 text-left'>{props.name}</Text>
      <ChevronRight className='h-4 w-4' />
    </Button>
  )
}

export default function WalletSelect(props: Props) {
  const { extensionProviders, mobileProviders, mobileConnect } = useShuttle()
  const [qrCodeUrl, setQRCodeUrl] = useState('')
  const [error, setError] = useState(props.error)
  const sortedExtensionProviders = extensionProviders.sort((a, b) => +b - +a)

  const handleConnectClick = (extensionProviderId: string) => {
    useStore.setState({
      focusComponent: <WalletConnecting providerId={extensionProviderId} />,
    })
  }

  const handleMobileConnectClick = async (mobileProviderId: string, chainId: string) => {
    try {
      const urls = await mobileConnect({
        mobileProviderId,
        chainId,
      })

      if (isMobile()) {
        if (isAndroid()) {
          window.location.href = urls.androidUrl
        } else if (isIOS()) {
          window.location.href = urls.iosUrl
        } else {
          window.location.href = urls.androidUrl
        }
      } else {
        setQRCodeUrl(urls.qrCodeUrl)
      }
    } catch (error) {
      if (error instanceof Error) {
        setError({ title: 'Failed to connect to wallet', message: error.message })
      }
    }
  }

  useEffect(() => {
    if (error?.message && error?.title) {
      useStore.setState({
        toast: {
          isError: true,
          title: error.title,
          message: error.message,
        },
      })
    }
  }, [error?.message, error?.title])

  if (qrCodeUrl)
    return (
      <FullOverlayContent
        title={'Scan the QR Code'}
        copy={
          'Open your mobile wallet App and use the QR Scan function to connect via WalletConnect v2'
        }
        button={{
          color: 'secondary',
          leftIcon: <ChevronLeft />,
          iconClassName: 'w-3',
          onClick: () => setQRCodeUrl(''),
          text: 'Back',
        }}
      >
        <div className='mb-4 rounded-sm bg-white p-2'>
          <QRCode value={qrCodeUrl} />
        </div>
      </FullOverlayContent>
    )

  return (
    <FullOverlayContent
      title={'Connect your wallet'}
      copy={`Deposit assets from your ${currentChain.name} address to your Mars credit account.`}
      docs='wallet'
    >
      <div className='flex w-full flex-wrap gap-3'>
        {!isMobile() && (
          <>
            {sortedExtensionProviders.map((provider) => {
              const walletId = provider.id as WalletID
              return (
                <React.Fragment key={walletId}>
                  {Array.from(provider.networks.values())
                    .filter((network) => network.chainId === currentChainId)
                    .map((network) => {
                      if (!provider.initialized && !provider.initializing) {
                        return (
                          <WalletOption
                            key={`${walletId}-${network.chainId}`}
                            handleClick={() => {
                              window.open(WALLETS[walletId].installURL ?? '/', '_blank')
                            }}
                            imageSrc={WALLETS[walletId].imageURL}
                            name={WALLETS[walletId].install ?? 'Install Wallet'}
                          />
                        )
                      }

                      return (
                        <WalletOption
                          key={`${walletId}-${network.chainId}`}
                          handleClick={() => handleConnectClick(walletId)}
                          imageSrc={WALLETS[walletId].imageURL}
                          name={WALLETS[walletId].name ?? 'Conenct Wallet'}
                        />
                      )
                    })}
                </React.Fragment>
              )
            })}
          </>
        )}
        {mobileProviders.map((provider) => {
          const walletId = provider.id as WalletID
          return (
            <React.Fragment key={walletId}>
              {Array.from(provider.networks.values())
                .filter((network) => network.chainId === currentChainId)
                .map((network) => {
                  return (
                    <WalletOption
                      key={`${walletId}-${network.chainId}`}
                      name={WALLETS[walletId].walletConnect ?? 'WalletConnect'}
                      imageSrc={WALLETS[walletId].mobileImageURL ?? '/'}
                      handleClick={() => handleMobileConnectClick(walletId, network.chainId)}
                    />
                  )
                })}
            </React.Fragment>
          )
        })}
      </div>
    </FullOverlayContent>
  )
}
