/**
 * LP 池数据读取 Hook
 * 集中管理所有池子状态的读取逻辑
 */

import { useMemo } from 'react'
import { useAccount, useChainId, useReadContract, useReadContracts } from 'wagmi'
import {
  getContracts,
  getDecimals,
  YT_REWARD_ROUTER_ABI,
  YT_LP_TOKEN_ABI,
  YT_POOL_MANAGER_ABI,
  YT_VAULT_ABI,
  YT_PRICE_FEED_ABI,
  FACTORY_ABI,
  USDY_ABI,
} from '@/config/contracts'
import { ERC20_BASE_ABI, type PoolToken } from './types'

// 扩展的池子代币类型
export interface ExtendedPoolToken extends PoolToken {
  balance?: bigint       // 用户钱包余额
  isWhitelisted?: boolean
  usdyAmount?: bigint    // 池内 USDY 债务量（合约层面）
  poolAmount?: bigint    // 池内代币数量（合约层面）
  minPrice?: bigint      // 代币最低价格（1e30 精度）
  usdyValue?: bigint     // 用户钱包余额对应的 USDY 价值（用户层面）
  isStable?: boolean
  weight?: bigint
}

// 管理员配置用的代币类型
export interface AvailableToken {
  address: string
  symbol: string
  name: string
  source: 'pool' | 'factory'
  isStable?: boolean
  isWhitelisted?: boolean
}

export function useLPPoolData() {
  const { address, isConnected } = useAccount()
  const chainId = useChainId()
  const CONTRACTS = getContracts(chainId)
  const TOKEN_DECIMALS = getDecimals(chainId)

  // ===== 动态获取 LP 池代币列表 =====
  const { data: rawPoolTokenAddresses } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'getAllPoolTokens',
  })

  // ===== 从 Factory 获取所有创建的金库 =====
  const { data: factoryVaults } = useReadContract({
    address: CONTRACTS.FACTORY,
    abi: FACTORY_ABI,
    functionName: 'getAllVaults',
  })

  // 去重处理
  const poolTokenAddresses = useMemo(() => {
    if (!rawPoolTokenAddresses || rawPoolTokenAddresses.length === 0) return []
    const seen = new Set<string>()
    return (rawPoolTokenAddresses as string[]).filter((addr: string) => {
      const lower = addr.toLowerCase()
      if (seen.has(lower)) return false
      seen.add(lower)
      return true
    })
  }, [rawPoolTokenAddresses])

  // 批量读取代币信息（symbol / name / decimals）— 每个代币 3 条
  const tokenInfoContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.flatMap((addr: string) => [
      { address: addr as `0x${string}`, abi: ERC20_BASE_ABI, functionName: 'symbol' as const },
      { address: addr as `0x${string}`, abi: ERC20_BASE_ABI, functionName: 'name' as const },
      { address: addr as `0x${string}`, abi: ERC20_BASE_ABI, functionName: 'decimals' as const },
    ])
  }, [poolTokenAddresses])

  const { data: tokenInfoResults } = useReadContracts({ contracts: tokenInfoContracts })

  // 批量读取 Factory 金库信息
  const factoryVaultInfoContracts = useMemo(() => {
    if (!factoryVaults || factoryVaults.length === 0) return []
    return (factoryVaults as string[]).flatMap((addr: string) => [
      { address: addr as `0x${string}`, abi: ERC20_BASE_ABI, functionName: 'symbol' as const },
      { address: addr as `0x${string}`, abi: ERC20_BASE_ABI, functionName: 'name' as const },
    ])
  }, [factoryVaults])

  const { data: factoryVaultInfoResults } = useReadContracts({ contracts: factoryVaultInfoContracts })

  // 批量读取用户余额
  const balanceContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0 || !address) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: addr as `0x${string}`,
      abi: ERC20_BASE_ABI,
      functionName: 'balanceOf' as const,
      args: [address] as const,
    }))
  }, [poolTokenAddresses, address])

  const { data: balanceResults, refetch: refetchTokenBalances } = useReadContracts({ contracts: balanceContracts })

  // 批量读取白名单状态
  const whitelistContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_VAULT as `0x${string}`,
      abi: YT_VAULT_ABI,
      functionName: 'whitelistedTokens' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: whitelistResults, refetch: refetchVaultWhitelist } = useReadContracts({ contracts: whitelistContracts })

  // 批量读取 usdyAmounts
  const usdyAmountsContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_VAULT as `0x${string}`,
      abi: YT_VAULT_ABI,
      functionName: 'usdyAmounts' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: usdyAmountsResults, refetch: refetchUsdyAmounts } = useReadContracts({ contracts: usdyAmountsContracts })

  // 批量读取稳定币状态
  const stableTokensContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_PRICE_FEED as `0x${string}`,
      abi: YT_PRICE_FEED_ABI,
      functionName: 'stableTokens' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: stableTokensResults } = useReadContracts({ contracts: stableTokensContracts })

  // 批量读取代币权重
  const tokenWeightsContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_VAULT as `0x${string}`,
      abi: YT_VAULT_ABI,
      functionName: 'tokenWeights' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: tokenWeightsResults, refetch: refetchTokenWeights } = useReadContracts({ contracts: tokenWeightsContracts })

  // 批量读取池内代币数量（合约层面）
  const poolAmountsContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_VAULT as `0x${string}`,
      abi: YT_VAULT_ABI,
      functionName: 'poolAmounts' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: poolAmountsResults, refetch: refetchPoolAmounts } = useReadContracts({ contracts: poolAmountsContracts })

  // 批量读取代币最低价格（1e30 精度，用于计算用户钱包 USDY 价值）
  const tokenPriceContracts = useMemo(() => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0 || !CONTRACTS.YT_PRICE_FEED) return []
    return poolTokenAddresses.map((addr: string) => ({
      address: CONTRACTS.YT_PRICE_FEED as `0x${string}`,
      abi: YT_PRICE_FEED_ABI,
      functionName: 'getMinPrice' as const,
      args: [addr] as const,
    }))
  }, [poolTokenAddresses])

  const { data: tokenPriceResults } = useReadContracts({ contracts: tokenPriceContracts })

  // 构建代币列表
  const poolTokens = useMemo((): ExtendedPoolToken[] => {
    if (!poolTokenAddresses || poolTokenAddresses.length === 0) return []
    return poolTokenAddresses.map((addr: string, index: number) => {
      // 每个代币 3 条：symbol[i*3] / name[i*3+1] / decimals[i*3+2]
      const symbol   = tokenInfoResults?.[index * 3]?.result as string | undefined
      const name     = tokenInfoResults?.[index * 3 + 1]?.result as string | undefined
      const decimals = (tokenInfoResults?.[index * 3 + 2]?.result as number | undefined) ?? TOKEN_DECIMALS.YT

      const balance     = balanceResults?.[index]?.result as bigint | undefined
      const isWhitelisted = whitelistResults?.[index]?.result as boolean | undefined
      const usdyAmount  = usdyAmountsResults?.[index]?.result as bigint | undefined
      const isStable    = stableTokensResults?.[index]?.result as boolean | undefined
      const weight      = tokenWeightsResults?.[index]?.result as bigint | undefined
      const poolAmount  = poolAmountsResults?.[index]?.result as bigint | undefined
      const minPrice    = tokenPriceResults?.[index]?.result as bigint | undefined

      // 用户钱包 USDY 价值 = balance(decimals) * minPrice(1e30) / 1e30 → 结果精度 = decimals
      const usdyValue = (balance && minPrice)
        ? (balance * minPrice) / 1000000000000000000000000000000n
        : undefined

      return {
        address: addr as `0x${string}`,
        symbol: symbol || `Token ${index}`,
        name: name || `Unknown Token ${index}`,
        decimals,
        balance,
        isWhitelisted,
        usdyAmount,
        poolAmount,
        minPrice,
        usdyValue,
        isStable,
        weight,
      }
    })
  }, [poolTokenAddresses, tokenInfoResults, balanceResults, whitelistResults, usdyAmountsResults, stableTokensResults, tokenWeightsResults, poolAmountsResults, tokenPriceResults])

  // 合并所有可用代币（用于管理员配置）
  const allAvailableTokens = useMemo((): AvailableToken[] => {
    const poolAddressSet = new Set(poolTokenAddresses?.map((a: string) => a.toLowerCase()) || [])

    const factoryOnlyTokens: AvailableToken[] = []
    if (factoryVaults && factoryVaults.length > 0) {
      (factoryVaults as string[]).forEach((addr: string, index: number) => {
        if (!poolAddressSet.has(addr.toLowerCase())) {
          const symbol = factoryVaultInfoResults?.[index * 2]?.result as string | undefined
          const name = factoryVaultInfoResults?.[index * 2 + 1]?.result as string | undefined
          factoryOnlyTokens.push({
            address: addr,
            symbol: symbol || `Vault ${index}`,
            name: name || `Factory Vault ${index}`,
            source: 'factory',
          })
        }
      })
    }

    const poolWithSource: AvailableToken[] = poolTokens.map(t => ({
      address: t.address,
      symbol: t.symbol,
      name: t.name,
      source: 'pool' as const,
      isStable: t.isStable,
      isWhitelisted: t.isWhitelisted,
    }))

    const usdcInList = [...poolWithSource, ...factoryOnlyTokens].some(
      t => t.address.toLowerCase() === CONTRACTS.USDC.toLowerCase()
    )

    const result: AvailableToken[] = [...poolWithSource, ...factoryOnlyTokens]
    if (!usdcInList) {
      result.push({
        address: CONTRACTS.USDC,
        symbol: 'USDC',
        name: 'USD Coin',
        source: 'pool',
      })
    }

    return result
  }, [poolTokens, poolTokenAddresses, factoryVaults, factoryVaultInfoResults])

  // ===== ytLP 代币信息 =====
  const { data: ytLPBalance, refetch: refetchBalance } = useReadContract({
    address: CONTRACTS.YT_LP_TOKEN,
    abi: YT_LP_TOKEN_ABI,
    functionName: 'balanceOf',
    args: address ? [address] : undefined,
  })

  const { data: ytLPTotalSupply, refetch: refetchYtLPTotalSupply } = useReadContract({
    address: CONTRACTS.YT_LP_TOKEN,
    abi: YT_LP_TOKEN_ABI,
    functionName: 'totalSupply',
  })

  const { data: ytLPDecimals } = useReadContract({
    address: CONTRACTS.YT_LP_TOKEN,
    abi: YT_LP_TOKEN_ABI,
    functionName: 'decimals',
  })

  const { data: ytLPName } = useReadContract({
    address: CONTRACTS.YT_LP_TOKEN,
    abi: YT_LP_TOKEN_ABI,
    functionName: 'name',
  })

  const { data: ytLPSymbol } = useReadContract({
    address: CONTRACTS.YT_LP_TOKEN,
    abi: YT_LP_TOKEN_ABI,
    functionName: 'symbol',
  })

  const { data: ytLPPrice, refetch: refetchYtLPPrice } = useReadContract({
    address: CONTRACTS.YT_REWARD_ROUTER,
    abi: YT_REWARD_ROUTER_ABI,
    functionName: 'getYtLPPrice',
  })

  // ===== 池子数据 =====
  const { data: aumInUsdy, refetch: refetchAumInUsdy } = useReadContract({
    address: CONTRACTS.YT_POOL_MANAGER,
    abi: YT_POOL_MANAGER_ABI,
    functionName: 'getAumInUsdy',
    args: [true],
  })

  const { data: cooldownDuration } = useReadContract({
    address: CONTRACTS.YT_POOL_MANAGER,
    abi: YT_POOL_MANAGER_ABI,
    functionName: 'cooldownDuration',
  })

  const { data: lastAddedAt } = useReadContract({
    address: CONTRACTS.YT_POOL_MANAGER,
    abi: YT_POOL_MANAGER_ABI,
    functionName: 'lastAddedAt',
    args: address ? [address] : undefined,
  })

  const { data: accountValue, refetch: refetchAccountValue } = useReadContract({
    address: CONTRACTS.YT_REWARD_ROUTER,
    abi: YT_REWARD_ROUTER_ABI,
    functionName: 'getAccountValue',
    args: address ? [address] : undefined,
  })

  // ===== 管理状态 =====
  const { data: emergencyMode, refetch: refetchEmergencyMode } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'emergencyMode',
  })

  const { data: swapEnabled, refetch: refetchSwapEnabled } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'isSwapEnabled',
  })

  const { data: poolPaused } = useReadContract({
    address: CONTRACTS.YT_POOL_MANAGER,
    abi: YT_POOL_MANAGER_ABI,
    functionName: 'paused',
  })

  // ===== 手续费配置 =====
  const { data: swapFee } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'swapFee',
  })

  const { data: stableSwapFee } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'stableSwapFee',
  })

  const { data: taxBasisPoints } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'taxBasisPoints',
  })

  const { data: stableTaxBasisPoints } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'stableTaxBasisPoints',
  })

  const { data: dynamicFees } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'dynamicFees',
  })

  // ===== 管理员地址 =====
  const { data: vaultGov } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'gov',
  })

  const { data: poolManagerGov } = useReadContract({
    address: CONTRACTS.YT_POOL_MANAGER,
    abi: YT_POOL_MANAGER_ABI,
    functionName: 'gov',
  })

  const { data: priceFeedGov } = useReadContract({
    address: CONTRACTS.YT_PRICE_FEED,
    abi: YT_PRICE_FEED_ABI,
    functionName: 'gov',
  })

  const { data: usdcPriceSource } = useReadContract({
    address: CONTRACTS.YT_PRICE_FEED,
    abi: YT_PRICE_FEED_ABI,
    functionName: 'usdcPriceSource',
  })

  // ===== USDY 信息 =====
  const { data: usdyTotalSupply, refetch: refetchUsdySupply } = useReadContract({
    address: CONTRACTS.USDY,
    abi: USDY_ABI,
    functionName: 'totalSupply',
  })

  const { data: poolValue, refetch: refetchPoolValue } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'getPoolValue',
  })

  // 辅助函数：根据地址获取代币符号
  const getTokenSymbol = (tokenAddress: string): string => {
    const token = poolTokens.find(t => t.address.toLowerCase() === tokenAddress.toLowerCase())
    return token?.symbol || 'Token'
  }

  return {
    // 连接状态
    address,
    isConnected,

    // 代币列表
    poolTokens,
    allAvailableTokens,
    poolTokenAddresses,

    // ytLP 数据
    ytLPBalance,
    ytLPTotalSupply,
    ytLPDecimals,
    ytLPName,
    ytLPSymbol,
    ytLPPrice,

    // 池子数据
    aumInUsdy,
    cooldownDuration,
    lastAddedAt,
    accountValue,
    poolValue,
    usdyTotalSupply,

    // 管理状态
    emergencyMode,
    swapEnabled,
    poolPaused,

    // 手续费
    swapFee,
    stableSwapFee,
    taxBasisPoints,
    stableTaxBasisPoints,
    dynamicFees,

    // 管理员地址
    vaultGov,
    poolManagerGov,
    priceFeedGov,
    usdcPriceSource,

    // 辅助函数
    getTokenSymbol,

    // Refetch 函数
    refetchBalance,
    refetchTokenBalances,
    refetchYtLPTotalSupply,
    refetchYtLPPrice,
    refetchAumInUsdy,
    refetchAccountValue,
    refetchUsdyAmounts,
    refetchTokenWeights,
    refetchPoolAmounts,
    refetchEmergencyMode,
    refetchSwapEnabled,
    refetchUsdySupply,
    refetchPoolValue,
    refetchVaultWhitelist,

    // 链信息
    chainId,
    TOKEN_DECIMALS,
    CONTRACTS,
  }
}
