import { ref, computed } from 'vue'
import {
  disconnect,
  getAccount,
  sendTransaction,
  switchChain,
  writeContract,
} from '@wagmi/core'
import {
  erc20Abi,
  getAddress,
  parseEther,
  parseUnits,
} from 'viem'
import {
  erc20DecimalsForChain,
  resolveEvmChainId,
} from '@/utils/evmRecharge'
import {
  abortActiveEvmConnectWait,
  waitForEvmConnectAfterModalOpen,
} from '@/utils/reownConnectWait'
import {
  getWagmiConfig,
  reownAppKit,
  reownEnabled,
} from '@/config/reownAppKit'
import type { RechargeFlatNetworkOption, RechargeOrderDetail } from '@/stores/deposit'

async function ensureEvmConnected(config: ReturnType<typeof getWagmiConfig>) {
  const account = getAccount(config)
  if (account.isConnected && account.address) {
    return
  }
  await reownAppKit?.open({ namespace: 'eip155', view: 'Connect' })
  await waitForEvmConnectAfterModalOpen()
}

async function ensureChain(config: ReturnType<typeof getWagmiConfig>, chainId: number) {
  const account = getAccount(config)
  if (account.chainId === chainId) {
    return
  }
  await switchChain(config, { chainId })
}

async function resetWalletConnectSession() {
  abortActiveEvmConnectWait()
  if (!reownEnabled) {
    return
  }
  try {
    await reownAppKit?.close()
    await reownAppKit?.disconnect('eip155')
    await disconnect(getWagmiConfig())
  } catch {
    // Reset is best-effort; the next click will create a fresh session.
  }
}

export { resetWalletConnectSession }

export function useWalletConnectDeposit() {
  const wcBusy = ref(false)
  const wcConfigured = computed(() => reownEnabled && reownAppKit != null)

  function resetWalletBusy() {
    wcBusy.value = false
    void resetWalletConnectSession()
  }

  function canPayWithWallet(
    network: RechargeFlatNetworkOption | null,
    order: RechargeOrderDetail | null,
  ): boolean {
    if (!network || !order || Number(order.status) !== 0) {
      return false
    }
    return resolveEvmChainId(network.protocol, network.networkName) !== null
  }

  /**
   * 通过 Reown AppKit（Injected + WalletConnect）连接 EVM 钱包并发起转账。
   * @returns 交易 hash（0x…）
   */
  async function connectAndPay(params: {
    network: RechargeFlatNetworkOption
    order: RechargeOrderDetail
  }): Promise<string> {
    const { network, order } = params
    const chainId = resolveEvmChainId(network.protocol, network.networkName)
    if (chainId == null) {
      throw new Error('当前网络不支持钱包支付，请使用对应链钱包手动转账')
    }
    if (!reownEnabled) {
      throw new Error('未配置 VITE_WALLETCONNECT_PROJECT_ID')
    }

    const config = getWagmiConfig()
    wcBusy.value = true
    try {
      await ensureEvmConnected(config)
      await ensureChain(config, chainId)

      const account = getAccount(config)
      const from = account.address
      if (!from) {
        throw new Error('未获取到钱包地址')
      }

      const to = getAddress(order.rechargeAddress as `0x${string}`)
      const amountStr = String(order.amount).trim()
      const contractAddr = network.contractAddress?.trim()

      if (contractAddr) {
        const token = getAddress(contractAddr as `0x${string}`)
        const decimals = erc20DecimalsForChain(chainId)
        const amountWei = parseUnits(amountStr, decimals)
        return await writeContract(config, {
          account: from,
          chainId,
          address: token,
          abi: erc20Abi,
          functionName: 'transfer',
          args: [to, amountWei],
        })
      }

      const valueWei = parseEther(amountStr)
      return await sendTransaction(config, {
        account: from,
        chainId,
        to,
        value: valueWei,
      })
    } finally {
      wcBusy.value = false
    }
  }

  return {
    wcBusy,
    wcConfigured,
    resetWalletBusy,
    clearWalletSession: resetWalletConnectSession,
    canPayWithWallet,
    connectAndPay,
  }
}
