import { useQuery, useQueries, useMutation } from '@tanstack/react-query'
import { useMe } from '@features/auth'
import { getWalletBalance, getPrices, sendWallet, getWalletAddresses, getPortfolio, getOrgPortfolio, getOrgWalletBalance, getOrgWalletAddresses, getTokensList, getRelayQuote, executeRelaySwap, signRawEvmTx, signSolTx, getTrxSwapQuote, executeTrxSwap, getJumperTokens, getJumperQuote, executeBridge, createWallet, revealMnemonic, CHAINS, type Chain, type SendWalletPayload, type RelayQuotePayload, type RelaySwapStep, type TrxSwapQuotePayload, type JumperQuotePayload, type BridgeExecutePayload } from '../api/walletApi'

/** Legal-entity accounts read wallet data from b2b instead of cryptowallet. */
function useIsLegalAccount() {
  const { data: me } = useMe()
  return { isLegal: me?.account_type === 'legal_entity', ready: !!me }
}

export function useWalletBalance(chain: Chain) {
  const { isLegal, ready } = useIsLegalAccount()
  return useQuery({
    queryKey: ['wallet', 'balance', chain, isLegal ? 'org' : 'self'],
    queryFn: isLegal ? () => getOrgWalletBalance(chain) : () => getWalletBalance(chain),
    // Wait for `me` before firing: otherwise a legal_entity account would hit
    // the cryptowallet endpoint during the brief window before account_type is known.
    enabled: ready,
    staleTime: 30_000,
  })
}

export function useAllWalletBalances() {
  return useQueries({
    queries: CHAINS.map(chain => ({
      queryKey: ['wallet', 'balance', chain],
      queryFn: () => getWalletBalance(chain),
      staleTime: 30_000,
    })),
  })
}

export function usePrices(symbols: string[]) {
  return useQuery({
    queryKey: ['wallet', 'prices', symbols.join(',')],
    queryFn: () => getPrices(symbols),
    staleTime: 5 * 60 * 1000,
  })
}

export function useSendWallet() {
  return useMutation({
    mutationFn: ({ chain, ...payload }: { chain: Chain } & SendWalletPayload) =>
      sendWallet(chain, payload),
  })
}

export function useWalletAddresses() {
  const { isLegal, ready } = useIsLegalAccount()
  return useQuery({
    queryKey: ['wallet', 'addresses', isLegal ? 'org' : 'self'],
    queryFn: isLegal ? getOrgWalletAddresses : getWalletAddresses,
    enabled: ready,
    staleTime: 10 * 60 * 1000,
  })
}

export function usePortfolio() {
  const { isLegal, ready } = useIsLegalAccount()
  return useQuery({
    queryKey: ['wallet', 'portfolio', isLegal ? 'org' : 'self'],
    queryFn: isLegal ? getOrgPortfolio : getPortfolio,
    enabled: ready,
    staleTime: 30_000,
  })
}

export function useTokensList() {
  return useQuery({
    queryKey: ['wallet', 'tokens'],
    queryFn: getTokensList,
    staleTime: 10 * 60 * 1000,
  })
}

export function useJumperTokens() {
  return useQuery({
    queryKey: ['wallet', 'jumper', 'tokens'],
    queryFn: getJumperTokens,
    staleTime: 10 * 60 * 1000,
  })
}

export function useJumperQuote(payload: JumperQuotePayload | null) {
  return useQuery({
    queryKey: ['wallet', 'jumper', 'quote',
      payload?.fromChain, payload?.toChain,
      payload?.fromToken, payload?.toToken,
      payload?.fromAmount, payload?.fromAddress, payload?.toAddress,
    ],
    queryFn: () => getJumperQuote(payload!),
    enabled: !!payload,
    staleTime: 10_000,
  })
}

export function useFetchJumperQuote() {
  return useMutation({ mutationFn: (payload: JumperQuotePayload) => getJumperQuote(payload) })
}

export function useExecuteBridge() {
  return useMutation({ mutationFn: (payload: BridgeExecutePayload) => executeBridge(payload) })
}

export function useCreateWallet() {
  return useMutation({ mutationFn: createWallet })
}

// `enabled` gates the request so callers can require an explicit user action
// (e.g. a "Показать" button) before the mnemonic is fetched. Defaults to true
// to preserve the standalone /seed-phrase page behavior.
export function useRevealMnemonic(enabled = true) {
  return useQuery({
    queryKey: ['wallet', 'mnemonic'],
    queryFn: revealMnemonic,
    staleTime: Infinity,
    retry: false,
    enabled,
  })
}

export function useRelayQuote(payload: RelayQuotePayload | null) {
  return useQuery({
    queryKey: ['relay', 'quote',
      payload?.originChainId, payload?.destinationChainId,
      payload?.originCurrency, payload?.destinationCurrency, payload?.amount,
    ],
    queryFn: () => getRelayQuote(payload!),
    enabled: !!payload,
    staleTime: 10_000,
  })
}

export function useExecuteRelaySwap() {
  return useMutation({
    mutationFn: (payload: RelayQuotePayload) => executeRelaySwap(payload),
  })
}

export function useSignSwap() {
  return useMutation({
    mutationFn: ({ chain, txData }: { chain: Chain; txData: unknown }) => {
      if (chain === 'SOL') return signSolTx(txData)
      return signRawEvmTx(chain as 'ETH' | 'BSC', txData as RelaySwapStep['items'][0]['data'])
    },
  })
}

export function useTrxSwapQuote(payload: TrxSwapQuotePayload | null) {
  return useQuery({
    queryKey: ['trx', 'quote', payload?.from, payload?.to, payload?.amountHuman],
    queryFn: () => getTrxSwapQuote(payload!),
    enabled: !!payload,
    staleTime: 10_000,
  })
}

export function useFetchTrxQuote() {
  return useMutation({ mutationFn: getTrxSwapQuote })
}

export function useExecuteTrxSwap() {
  return useMutation({ mutationFn: (quoteId: string) => executeTrxSwap(quoteId) })
}
