/*
 * Copyright (c) 2022 @automata-network/wallet-sdk authors and contributors.
 * This software may be modified and distributed under the terms of UNLICENSED
 * license. Refer to the LICENSE file for details.
 */
import React, { useState } from 'react'

import { Injected } from '@polkadot/extension-inject/types'

import { PolkadotExtensionModule } from '../../core/interfaces'
import { usePolkadotConnectorContext } from '../../store/polkadot-connector/hook'
import { useWallet } from '../../store/wallet'
import { userCanceledError } from '../../utils'
import { Connector, ConnectorItem } from '../Connector/Connector'

interface ConnectorContextData {
  loading: boolean
  injected?: Injected
  error?: Error
}

const initialConnectorContextData = {
  loading: false,
  error: undefined
}

export const PolkadotConnector: React.FC = () => {
  const { appName } = useWallet()
  const { extensionModules, setExtensionModules, connectionPromise } = usePolkadotConnectorContext()
  const [data, setData] = useState<ConnectorContextData>(initialConnectorContextData)

  async function getExtension(extensionModule: PolkadotExtensionModule) {
    setData({ loading: true })

    try {
      const result = await extensionModule.getInjected(appName || '')
      const accounts = result ? await result.injected.accounts.get() : []

      if (connectionPromise && result) {
        connectionPromise.resolve({
          label: extensionModule.label,
          icon: extensionModule.getIcon(),
          injected: result.injected,
          accounts: accounts.map((item) => item.address)
        })
      }

      setExtensionModules(undefined)

      setData(initialConnectorContextData)
    } catch (e) {
      if (connectionPromise) {
        connectionPromise.reject(e as Error)
      }

      setData({ loading: false, error: e as Error })

      throw e
    }
  }

  return extensionModules ? (
    <Connector
      loading={data.loading}
      error={data.error}
      items={
        extensionModules
          .map((item) => {
            const enabled = item.isEnabled()
            const link = item.getInstallLink ? item.getInstallLink() : undefined
            const icon = item.getIcon()

            return enabled || link ? { enabled, link, icon, label: item.label } : undefined
          })
          .filter((item) => item != null) as ConnectorItem[]
      }
      onSelect={(index) => {
        getExtension(extensionModules[index])
      }}
      onClose={() => {
        setExtensionModules(undefined)

        connectionPromise?.reject(userCanceledError)
      }}
    />
  ) : null
}
