import {ChevronDownIcon, ChevronRightIcon,} from '@heroicons/react/solid'
import React, {useEffect, useMemo, useState} from 'react'
import {useNavigate} from 'react-router-dom'
import {FiCopy, FiKey, FiPlay, FiTrash2, FiTrendingUp} from 'react-icons/fi'

import useApiUrlStore from '../../../app/store/apiStore'
import {SelectColumnFilter, Table, Toast,} from '../../../components/mollecules'
import type {Account} from '../../../generated/ManagingApi'
import {AccountClient, AccountType, TradingClient} from '../../../generated/ManagingApi'

import AccountRowDetails from './accountRowDetails'
import PrivyDelegationModal from './PrivyDelegationModal'
import GmxPositionModal from './GmxPositionModal'

interface IAccountList {
  list: Account[]
  isFetching: boolean
}

const AccountTable: React.FC<IAccountList> = ({ list, isFetching }) => {
  const [rows, setRows] = useState<Account[]>([])
  const { apiUrl } = useApiUrlStore()
  const navigate = useNavigate()
  const [modalAccount, setModalAccount] = useState<Account | null>(null)
  const [isDelegationModalOpen, setIsDelegationModalOpen] = useState(false)
  const [isGmxPositionModalOpen, setIsGmxPositionModalOpen] = useState(false)

  async function deleteAcount(accountName: string) {
    const t = new Toast('Deleting money management')
    const client = new AccountClient({}, apiUrl)

    await client
      .account_DeleteAccount(accountName)
      .then(() => {
        t.update('success', 'Account deleted')
      })
      .catch((err) => {
        t.update('error', 'Error :' + err)
      })
  }

  async function initPrivyWallet(publicAddress: string) {
    const t = new Toast('Initializing Privy wallet')
    const client = new TradingClient({}, apiUrl)

    try {
      const response = await client.trading_InitPrivyWallet(publicAddress)
      if (response.success) {
        t.update('success', 'Privy wallet initialized successfully')
      } else {
        t.update('error', `Initialization failed: ${response.error || 'Unknown error'}`)
      }
    } catch (err) {
      t.update('error', 'Error: ' + err)
    }
  }

  async function copyToClipboard(text: string) {
    const t = new Toast('Copying to clipboard...')
    try {
      await navigator.clipboard.writeText(text)
      t.update('success', 'Address copied to clipboard!')
    } catch (err) {
      t.update('error', 'Failed to copy to clipboard')
    }
  }

  const columns = useMemo(
    () => [
      {
        Cell: ({ row }: any) => (
          <span {...row.getToggleRowExpandedProps()}>
            {row.isExpanded ? (
              <ChevronDownIcon></ChevronDownIcon>
            ) : (
              <ChevronRightIcon></ChevronRightIcon>
            )}
          </span>
        ),

        // Make sure it has an ID
        Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }: any) => (
          <span {...getToggleAllRowsExpandedProps()}>
            {isAllRowsExpanded ? 'v' : '>'}
          </span>
        ),
        // Build our expander column
        id: 'expander',
      },
      {
        Header: 'Name',
        accessor: 'name',
        disableFilters: true,
      },
      {
        Filter: SelectColumnFilter,
        Header: 'Exchange',
        accessor: 'exchange',
        disableSortBy: true,
      },
      {
        Filter: SelectColumnFilter,
        Header: 'Type',
        accessor: 'type',
        disableSortBy: true,
      },
      {
        Cell: ({ cell }: any) => (
          <>
            <div className="flex items-center space-x-2">
              <div className="tooltip" data-tip={cell.row.values.key}>
                {cell.row.values.key.substring(0, 6)}...
                {cell.row.values.key.slice(-4)}
              </div>
              <button
                className="btn btn-xs btn-ghost"
                onClick={() => copyToClipboard(cell.row.values.key)}
                title="Copy full address"
              >
                <FiCopy className="h-3 w-3" />
              </button>
            </div>
          </>
        ),
        Header: 'Key',
        accessor: 'key',
        disableFilters: true,
      },
      {
        Cell: ({ row }: any) => {
          const account = row.original

          return (
            <div className="flex space-x-2">
              <button
                className="btn btn-sm btn-error btn-outline"
                onClick={() => deleteAcount(account.name)}
              >
                <FiTrash2 />
              </button>

              {account.type === AccountType.Privy && (
                <>
                  <button
                    className="btn btn-sm btn-primary btn-outline"
                    onClick={() => {
                      setModalAccount(account)
                      setIsDelegationModalOpen(true)
                    }}
                  >
                    <FiKey />
                    <span className="ml-1">Delegate</span>
                  </button>

                  <button
                    className="btn btn-sm btn-info btn-outline"
                    onClick={() => initPrivyWallet(account.key)}
                  >
                    <FiPlay />
                    <span className="ml-1">Init</span>
                  </button>

                  <button
                    className="btn btn-sm btn-success btn-outline"
                    onClick={() => {
                      setModalAccount(account)
                      setIsGmxPositionModalOpen(true)
                    }}
                  >
                    <FiTrendingUp />
                    <span className="ml-1">GMX</span>
                  </button>
                </>
              )}
            </div>
          )
        },
        Header: 'Actions',
        accessor: 'id',
        disableFilters: true,
      },
    ],
    []
  )

  useEffect(() => {
    setRows(list)
  }, [list])

  const renderRowSubComponent = React.useCallback(
    ({ row }: { row: any }) => {
      const { balances } = row.original
      return (
        <>
          {balances && balances.length > 0 ? (
            <AccountRowDetails
              balances={balances}
              showTotal={true}
              account={row.original}
            ></AccountRowDetails>
          ) : (
            <div>No balances</div>
          )}
        </>
      )
    },
    []
  )

  return (
    <>
      {isFetching ? (
        <div>
          <progress className="progress progress-primary w-56"></progress>
        </div>
      ) : (
        <Table
          columns={columns}
          data={rows}
          renderRowSubCompontent={renderRowSubComponent}
        />
      )}

      {modalAccount && (
        <>
          <PrivyDelegationModal
            isOpen={isDelegationModalOpen}
            onClose={() => {
              setIsDelegationModalOpen(false)
              setModalAccount(null)
            }}
            account={modalAccount}
          />
          <GmxPositionModal
            isOpen={isGmxPositionModalOpen}
            onClose={() => {
              setIsGmxPositionModalOpen(false)
              setModalAccount(null)
            }}
            account={modalAccount}
          />
        </>
      )}
    </>
  )
}

export default AccountTable
