import { useState, useEffect, useRef, useMemo } from 'react';
import { useIntl } from '@umijs/max';
import { PageContainer, ProCard, StatisticCard } from '@ant-design/pro-components';
import {
  Tabs, Input, Button, Space, Typography, Select, Row, Col,
  message, Alert, Collapse, Descriptions, Badge, Tag, Table, Tooltip, DatePicker,
} from 'antd';
import dayjs from 'dayjs';
import {
  ShoppingCartOutlined, DollarOutlined, SendOutlined, WalletOutlined,
  SettingOutlined, CopyOutlined, InfoCircleOutlined, ThunderboltOutlined,
  SafetyOutlined, SwapOutlined, WarningOutlined, UserOutlined,
} from '@ant-design/icons';
import {
  useAccount, useReadContract, useReadContracts, useWriteContract,
  useWaitForTransactionReceipt, useChainId,
} from 'wagmi';
import { parseUnits, formatUnits } from 'viem';
import {
  GAS_CONFIG, VAULT_ABI, USDC_ABI, FACTORY_ABI,
  YT_REWARD_ROUTER_ABI, YT_VAULT_ABI, YT_PRICE_FEED_ABI,
  getContracts, getDecimals, getChainName,
} from '@/config/contracts';
import { useTransactions } from '@/context/TransactionContext';
import type { TransactionType } from '@/context/TransactionContext';
import { TransactionHistory } from '@/components/TransactionHistory';

const { Text } = Typography;

export default function VaultTradePage() {
  const intl = useIntl();
  const { address, isConnected } = useAccount();
  const chainId = useChainId();
  const CONTRACTS = getContracts(chainId);
  const TOKEN_DECIMALS = getDecimals(chainId);
  const currentChainName = getChainName(chainId);

  const { transactions, addTransaction, updateTransaction, clearHistory } = useTransactions();
  const pendingTxRef = useRef<{ id: string; type: TransactionType; amount?: string } | null>(null);
  const testTypeRef = useRef<string | null>(null);

  // ===== 基础状态 =====
  const [vaultList, setVaultList] = useState<{ name: string; address: string }[]>([]);
  const [selectedVault, setSelectedVault] = useState<{ name: string; address: string }>({ name: '', address: '' });
  const [buyAmount, setBuyAmount] = useState('');
  const [sellAmount, setSellAmount] = useState('');
  const [transferYtTo, setTransferYtTo] = useState('');
  const [transferYtAmount, setTransferYtAmount] = useState('');
  const [activeTab, setActiveTab] = useState('buy');

  // 管理员配置状态
  const [priceUpdateForm, setPriceUpdateForm] = useState({ ytPrice: '1' });
  const [hardCapForm, setHardCapForm] = useState('');
  const [redemptionTimeForm, setRedemptionTimeForm] = useState('');
  const [managerForm, setManagerForm] = useState('');
  const [priceWarning, setPriceWarning] = useState<{ message: string; changePct: number } | null>(null);

  // Manager 资产管理
  const [depositManagedAmount, setDepositManagedAmount] = useState('');
  const [withdrawManagedAmount, setWithdrawManagedAmount] = useState('');
  const [withdrawToAddress, setWithdrawToAddress] = useState('');

  // 倒计时 & 批量
  const [countdown, setCountdown] = useState<number>(0);
  const [batchSize, setBatchSize] = useState('10');

  // 硬顶 Swap
  const [hardcapSwapAmount, setHardcapSwapAmount] = useState('');
  const [hardcapSwapSlippage, setHardcapSwapSlippage] = useState('0.5');

  // 边界测试
  const [testResult, setTestResult] = useState<{ type: 'success' | 'error' | 'pending'; msg: string } | null>(null);
  const [isTestRunning, setIsTestRunning] = useState(false);

  // ===== 从工厂合约读取所有金库 =====
  const { data: allVaultsData } = useReadContract({
    address: CONTRACTS.FACTORY,
    abi: FACTORY_ABI,
    functionName: 'getAllVaults',
  });

  const vaultSymbolContracts = allVaultsData?.map((vaultAddr) => ({
    address: vaultAddr as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'symbol' as const,
  })) || [];

  const { data: vaultSymbolsData } = useReadContracts({ contracts: vaultSymbolContracts });

  useEffect(() => {
    if (allVaultsData && allVaultsData.length > 0) {
      const newVaultList = allVaultsData.map((vaultAddr, index) => {
        const symbolResult = vaultSymbolsData?.[index];
        const symbol = symbolResult?.status === 'success' ? symbolResult.result as string : `Vault ${index + 1}`;
        return { name: symbol, address: vaultAddr };
      });
      setVaultList(newVaultList);
      if (newVaultList[0] && (!selectedVault.address || !newVaultList.find(v => v.address.toLowerCase() === selectedVault.address.toLowerCase()))) {
        setSelectedVault(newVaultList[0]);
      }
    }
  }, [allVaultsData, vaultSymbolsData]);

  // ===== 金库基础信息读取 =====
  // getVaultInfo 返回结构 (VaultPanel 索引):
  // [0]=totalAssets(USDC), [1]=idleAssets(USDC), [2]=managedAssets(USDC),
  // [3]=totalSupply(YT), [4]=hardCap(YT), [5]=usdcPrice(8dec), [6]=ytPrice(30dec)
  const { data: vaultInfo, refetch: refetchVaultInfo } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'getVaultInfo',
  });

  const { data: ytBalance, refetch: refetchYtBalance } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'balanceOf',
    args: address ? [address] : undefined,
  });

  const { data: usdcBalance, refetch: refetchUsdcBalance } = useReadContract({
    address: CONTRACTS.USDC,
    abi: USDC_ABI,
    functionName: 'balanceOf',
    args: address ? [address] : undefined,
  });

  const { data: usdcAllowance, refetch: refetchAllowance } = useReadContract({
    address: CONTRACTS.USDC,
    abi: USDC_ABI,
    functionName: 'allowance',
    args: address ? [address, selectedVault.address as `0x${string}`] : undefined,
  });

  const { data: previewBuyAmount } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'previewBuy',
    args: buyAmount ? [parseUnits(buyAmount, TOKEN_DECIMALS.USDC)] : undefined,
  });

  const { data: previewSellAmount } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'previewSell',
    args: sellAmount ? [parseUnits(sellAmount, TOKEN_DECIMALS.YT)] : undefined,
  });

  const { data: vaultSymbol } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'symbol',
  });

  const { data: vaultName } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'name',
  });

  // ===== 赎回 & 角色读取 =====
  const { data: canRedeem } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'canRedeemNow',
  });

  const { data: timeUntilRedeem } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'getTimeUntilNextRedemption',
  });

  const { data: vaultManager } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'manager',
  });

  const { data: factoryOwner } = useReadContract({
    address: CONTRACTS.FACTORY,
    abi: FACTORY_ABI,
    functionName: 'owner',
  });

  const { data: vaultFactory } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'factory',
  });

  const { data: vaultUsdcAddress } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'usdcAddress',
  });

  const { data: pricePrecision } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'PRICE_PRECISION',
  });

  // Manager USDC 授权额度
  const { data: managerUsdcAllowance, refetch: refetchManagerAllowance } = useReadContract({
    address: CONTRACTS.USDC,
    abi: USDC_ABI,
    functionName: 'allowance',
    args: address ? [address, selectedVault.address as `0x${string}`] : undefined,
  });

  // ===== 硬顶 Swap 相关读取 =====
  const { data: usdcRouterAllowance, refetch: refetchUsdcRouterAllowance } = useReadContract({
    address: CONTRACTS.USDC,
    abi: USDC_ABI,
    functionName: 'allowance',
    args: address ? [address, CONTRACTS.YT_REWARD_ROUTER] : undefined,
  });

  const { data: usdcVaultAllowance } = useReadContract({
    address: CONTRACTS.USDC,
    abi: USDC_ABI,
    functionName: 'allowance',
    args: address ? [address, CONTRACTS.YT_VAULT] : undefined,
  });

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

  const { data: usdcWhitelisted } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'whitelistedTokens',
    args: [CONTRACTS.USDC],
  });

  const { data: targetYtWhitelisted } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'whitelistedTokens',
    args: [selectedVault.address as `0x${string}`],
  });

  const { data: usdcMinPrice } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'getMinPrice',
    args: [CONTRACTS.USDC],
  });

  const { data: targetYtMaxPrice } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'getMaxPrice',
    args: [selectedVault.address as `0x${string}`],
  });

  const { data: targetYtPoolAmount } = useReadContract({
    address: CONTRACTS.YT_VAULT,
    abi: YT_VAULT_ABI,
    functionName: 'poolAmounts',
    args: [selectedVault.address as `0x${string}`],
  });

  // ===== YTPriceFeed 读取 =====
  const { data: ytLastPrice, refetch: refetchYtLastPrice } = useReadContract({
    address: CONTRACTS.YT_PRICE_FEED as `0x${string}`,
    abi: YT_PRICE_FEED_ABI,
    functionName: 'lastPrice',
    args: [selectedVault.address as `0x${string}`],
    query: { enabled: !!CONTRACTS.YT_PRICE_FEED },
  });

  const { data: maxPriceChangeBps } = useReadContract({
    address: CONTRACTS.YT_PRICE_FEED as `0x${string}`,
    abi: YT_PRICE_FEED_ABI,
    functionName: 'maxPriceChangeBps',
    query: { enabled: !!CONTRACTS.YT_PRICE_FEED },
  });

  // ===== 排队退出读取 =====
  const { data: queueProgress, refetch: refetchQueueProgress } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'getQueueProgress',
  });

  const pendingRequestsContracts = useMemo(() => {
    if (!queueProgress) return [];
    const currentIndex = Number((queueProgress as any)[0] || 0);
    const totalRequests = Number((queueProgress as any)[1] || 0);
    const maxShow = Math.min(totalRequests - currentIndex, 20);
    const contracts = [];
    for (let i = 0; i < maxShow; i++) {
      contracts.push({
        address: selectedVault.address as `0x${string}`,
        abi: VAULT_ABI,
        functionName: 'withdrawRequests' as const,
        args: [BigInt(currentIndex + i)] as const,
      });
    }
    return contracts;
  }, [queueProgress, selectedVault.address]);

  const { data: pendingRequestsData } = useReadContracts({ contracts: pendingRequestsContracts });

  const pendingRequestsList = useMemo(() => {
    if (!pendingRequestsData || !queueProgress) return [];
    const currentIndex = Number((queueProgress as any)[0] || 0);
    return pendingRequestsData
      .map((result, index) => {
        if (result.status !== 'success') return null;
        const data = result.result as any;
        return {
          requestId: currentIndex + index,
          user: data[0] as string,
          ytAmount: data[1] as bigint,
          usdcAmount: data[2] as bigint,
          requestTime: data[3] as bigint,
          processed: data[5] as boolean,
        };
      })
      .filter((item): item is NonNullable<typeof item> => item !== null && !item.processed);
  }, [pendingRequestsData, queueProgress]);

  const { data: userPendingRequests, refetch: refetchUserPendingRequests } = useReadContract({
    address: selectedVault.address as `0x${string}`,
    abi: VAULT_ABI,
    functionName: 'getUserPendingRequests',
    args: address ? [address] : undefined,
  });

  // ===== 计算值 =====
  const isOwner = !!(address && factoryOwner &&
    (address as string).toLowerCase() === (factoryOwner as string).toLowerCase());
  const isManager = !!(address && vaultManager &&
    (address as string).toLowerCase() === (vaultManager as string).toLowerCase());
  const currentRole = isOwner ? 'Owner' : isManager ? 'Manager' : 'User';

  const isAtHardCap = useMemo(() => {
    if (!vaultInfo) return false;
    const vi = vaultInfo as any;
    const totalSupply = vi[3] as bigint;
    const hardCap = vi[4] as bigint;
    return hardCap > 0n && totalSupply >= hardCap;
  }, [vaultInfo]);

  const hardcapSwapPreview = useMemo(() => {
    if (!hardcapSwapAmount || !usdcMinPrice || !targetYtMaxPrice) return null;
    if ((targetYtMaxPrice as bigint) === 0n) return null;
    try {
      const amountIn = parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC);
      return (amountIn * (usdcMinPrice as bigint)) / (targetYtMaxPrice as bigint);
    } catch { return null; }
  }, [hardcapSwapAmount, usdcMinPrice, targetYtMaxPrice]);

  const needsHardcapSwapApproval = useMemo(() => {
    if (!usdcRouterAllowance || !hardcapSwapAmount) return false;
    try { return (usdcRouterAllowance as bigint) < parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC); }
    catch { return false; }
  }, [usdcRouterAllowance, hardcapSwapAmount]);

  const needsVaultApproval = useMemo(() => {
    if (usdcVaultAllowance === undefined || !hardcapSwapAmount) return false;
    try { return (usdcVaultAllowance as bigint) < parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC); }
    catch { return false; }
  }, [usdcVaultAllowance, hardcapSwapAmount]);

  const managerNeedsApproval = depositManagedAmount
    ? (managerUsdcAllowance === undefined || parseUnits(depositManagedAmount, TOKEN_DECIMALS.USDC) > (managerUsdcAllowance as bigint))
    : false;

  const { writeContract, data: hash, isPending, error: writeError, reset, status: writeStatus } = useWriteContract();
  const { isLoading: isConfirming, isSuccess, isError, error: txError } = useWaitForTransactionReceipt({ hash });

  // ===== Effects =====
  useEffect(() => {
    let timeoutId: NodeJS.Timeout | null = null;
    if (isPending && !hash) {
      timeoutId = setTimeout(() => {
        if (pendingTxRef.current) {
          updateTransaction(pendingTxRef.current.id, { status: 'failed', error: 'Transaction timeout' });
          pendingTxRef.current = null;
        }
        message.error(intl.formatMessage({ id: 'pages.toast.txTimeout' }));
        reset();
      }, 30000);
    }
    return () => { if (timeoutId) clearTimeout(timeoutId); };
  }, [isPending, hash]);

  useEffect(() => {
    if (hash && typeof hash === 'string' && hash.startsWith('0x') && pendingTxRef.current) {
      updateTransaction(pendingTxRef.current.id, { hash, status: 'pending' });
      message.info(intl.formatMessage({ id: 'pages.toast.txSubmitted' }));
    }
  }, [hash]);

  useEffect(() => {
    if (isSuccess) {
      if (pendingTxRef.current) {
        updateTransaction(pendingTxRef.current.id, { status: 'success' });
        message.success(intl.formatMessage({ id: 'pages.toast.txSuccess' }));
        pendingTxRef.current = null;
      }
      if (isTestRunning) {
        setTestResult({ type: 'success', msg: `[${testTypeRef.current}] 交易成功 (预期应失败)` });
        setIsTestRunning(false);
        testTypeRef.current = null;
      }
      refetchVaultInfo();
      refetchYtBalance();
      refetchUsdcBalance();
      refetchAllowance();
      refetchManagerAllowance();
      refetchUsdcRouterAllowance();
      refetchQueueProgress();
      refetchUserPendingRequests();
      if (CONTRACTS.YT_PRICE_FEED) refetchYtLastPrice();
      setBuyAmount('');
      setSellAmount('');
      setDepositManagedAmount('');
      setWithdrawManagedAmount('');
      setTransferYtAmount('');
      setTransferYtTo('');
      setHardcapSwapAmount('');
    }
  }, [isSuccess]);

  useEffect(() => {
    if (isError) {
      if (pendingTxRef.current) {
        const errMsg = typeof txError?.message === 'string' ? txError.message : 'Transaction failed';
        updateTransaction(pendingTxRef.current.id, { status: 'failed', error: errMsg });
        message.error(intl.formatMessage({ id: 'pages.toast.txFailed' }));
        pendingTxRef.current = null;
        reset();
      }
      if (isTestRunning) {
        const errorMsg = parseError(txError);
        setTestResult({ type: 'error', msg: `[${testTypeRef.current}] ${errorMsg}` });
        setIsTestRunning(false);
        testTypeRef.current = null;
      }
    }
  }, [isError]);

  useEffect(() => {
    if (writeError) {
      const errorMsg = parseError(writeError);
      message.error(errorMsg);
      if (pendingTxRef.current) {
        updateTransaction(pendingTxRef.current.id, { status: 'failed', error: errorMsg });
        pendingTxRef.current = null;
      }
      if (isTestRunning) {
        setTestResult({ type: 'error', msg: `[${testTypeRef.current}] ${errorMsg}` });
        setIsTestRunning(false);
        testTypeRef.current = null;
      }
      reset();
    }
  }, [writeError]);

  // 倒计时同步
  useEffect(() => {
    if (timeUntilRedeem !== undefined) {
      setCountdown(Number(timeUntilRedeem));
    }
  }, [timeUntilRedeem]);

  useEffect(() => {
    if (countdown <= 0) return;
    const timer = setInterval(() => setCountdown(prev => Math.max(0, prev - 1)), 1000);
    return () => clearInterval(timer);
  }, [countdown > 0]);

  // ===== 工具函数 =====
  const parseError = (error: any): string => {
    let msg = 'Unknown error';
    if (typeof error === 'string') msg = error;
    else if (error?.shortMessage) msg = error.shortMessage;
    else if (typeof error?.message === 'string') msg = error.message;
    else if (error?.message) msg = JSON.stringify(error.message);
    else if (error) { try { msg = JSON.stringify(error); } catch { msg = String(error); } }

    // 忽略动态模块加载错误，尝试获取真正的合约错误
    if (msg.includes('Failed to fetch dynamically imported module') || msg.includes('ccip')) {
      if (error?.cause) return parseError(error.cause);
      if (error?.error) return parseError(error.error);
      return 'Contract call failed';
    }

    if (msg.includes('User rejected') || msg.includes('user rejected'))
      return intl.formatMessage({ id: 'pages.toast.userRejected' });
    if (msg.includes('insufficient funds') || msg.includes('InsufficientBalance') || msg.includes('less than block base fee'))
      return intl.formatMessage({ id: 'pages.toast.insufficientBalance' }) + ' (Gas)';
    const customErrorMatch = msg.match(/reverted with custom error '(\w+)\(/i);
    if (customErrorMatch) return customErrorMatch[1];
    const revertMatch = msg.match(/reverted with reason string '([^']+)'/i);
    if (revertMatch) return revertMatch[1];
    const errorMatch = msg.match(/error[:\s]+(\w+)/i);
    if (errorMatch) return errorMatch[1];
    return msg.slice(0, 100);
  };

  const recordTx = (type: TransactionType, amount?: string, token?: string) => {
    const id = addTransaction({ type, hash: '', status: 'pending', amount, token });
    pendingTxRef.current = { id, type, amount };
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    message.success('已复制');
  };

  const formatTimeRemaining = (seconds: number): string => {
    if (seconds <= 0) return '0s';
    const days = Math.floor(seconds / 86400);
    const hours = Math.floor((seconds % 86400) / 3600);
    const mins = Math.floor((seconds % 3600) / 60);
    const secs = seconds % 60;
    const parts: string[] = [];
    if (days > 0) parts.push(`${days}d`);
    if (hours > 0) parts.push(`${hours}h`);
    if (mins > 0) parts.push(`${mins}m`);
    if (secs > 0 || parts.length === 0) parts.push(`${secs}s`);
    return parts.join(' ');
  };

  const isProcessing = (isPending || isConfirming) && writeStatus !== 'error';

  // ===== 交易处理函数 =====
  const handleApprove = () => {
    if (!buyAmount) return;
    recordTx('approve', buyAmount, 'USDC');
    writeContract({
      address: CONTRACTS.USDC, abi: USDC_ABI, functionName: 'approve',
      args: [selectedVault.address as `0x${string}`, parseUnits(buyAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.SIMPLE,
    });
  };

  const handleBuy = () => {
    if (!buyAmount) return;
    recordTx('buy', buyAmount, vaultSymbol as string);
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'depositYT',
      args: [parseUnits(buyAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleSell = () => {
    if (!sellAmount) return;
    recordTx('sell', sellAmount, vaultSymbol as string);
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'withdrawYT',
      args: [parseUnits(sellAmount, TOKEN_DECIMALS.YT)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleTransferYt = () => {
    if (!transferYtTo || !transferYtAmount) return;
    if (!transferYtTo.startsWith('0x') || transferYtTo.length !== 42) {
      message.error(intl.formatMessage({ id: 'pages.usdc.invalidAddress' }));
      return;
    }
    recordTx('transfer', transferYtAmount, vaultSymbol as string);
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'transfer',
      args: [transferYtTo as `0x${string}`, parseUnits(transferYtAmount, TOKEN_DECIMALS.YT)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  // ===== 硬顶 Swap =====
  const handleApproveUsdcForRouter = () => {
    if (!hardcapSwapAmount) return;
    recordTx('approve', hardcapSwapAmount, 'USDC->Router');
    writeContract({
      address: CONTRACTS.USDC, abi: USDC_ABI, functionName: 'approve',
      args: [CONTRACTS.YT_REWARD_ROUTER, parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.SIMPLE,
    });
  };

  const handleApproveUsdcForVault = () => {
    if (!hardcapSwapAmount) return;
    recordTx('approve', hardcapSwapAmount, 'USDC->Vault');
    writeContract({
      address: CONTRACTS.USDC, abi: USDC_ABI, functionName: 'approve',
      args: [CONTRACTS.YT_VAULT, parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.SIMPLE,
    });
  };

  const handleHardcapSwap = () => {
    if (!hardcapSwapAmount || !address) return;
    const amountIn = parseUnits(hardcapSwapAmount, TOKEN_DECIMALS.USDC);
    const slippageBps = Math.floor(parseFloat(hardcapSwapSlippage) * 100);
    let minOut = 0n;
    if (hardcapSwapPreview) {
      minOut = (hardcapSwapPreview as bigint) - ((hardcapSwapPreview as bigint) * BigInt(slippageBps) / 10000n);
    }
    recordTx('swap', hardcapSwapAmount, `USDC -> ${selectedVault.name}`);
    writeContract({
      address: CONTRACTS.YT_REWARD_ROUTER, abi: YT_REWARD_ROUTER_ABI, functionName: 'swapYT',
      args: [CONTRACTS.USDC, selectedVault.address as `0x${string}`, amountIn, minOut, address],
      gas: GAS_CONFIG.COMPLEX,
    });
  };

  // ===== 管理员功能 =====
  const handleUpdatePrices = () => {
    const ytPrice = parseUnits(priceUpdateForm.ytPrice, TOKEN_DECIMALS.INTERNAL_PRICE);
    if (ytLastPrice && (ytLastPrice as bigint) > 0n && maxPriceChangeBps) {
      const oldPrice = ytLastPrice as bigint;
      const priceDiff = ytPrice > oldPrice ? ytPrice - oldPrice : oldPrice - ytPrice;
      const changePercentBps = (priceDiff * 10000n) / oldPrice;
      const changePct = Number(changePercentBps) / 100;
      if (changePercentBps > (maxPriceChangeBps as bigint)) {
        const maxChangePct = Number(maxPriceChangeBps as bigint) / 100;
        setPriceWarning({ message: `⚠️ 价格变化 ${changePct.toFixed(2)}% 超过允许最大值 ${maxChangePct.toFixed(2)}%`, changePct });
      } else {
        setPriceWarning(null);
      }
    }
    recordTx('test', priceUpdateForm.ytPrice, 'UpdateYtPrice');
    writeContract({
      address: CONTRACTS.FACTORY, abi: FACTORY_ABI, functionName: 'updateVaultPrices',
      args: [selectedVault.address as `0x${string}`, ytPrice],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleUpdateYTPriceFeed = () => {
    if (!CONTRACTS.YT_PRICE_FEED) { message.warning('YT_PRICE_FEED 合约地址未配置'); return; }
    const ytPrice = parseUnits(priceUpdateForm.ytPrice, TOKEN_DECIMALS.INTERNAL_PRICE);
    recordTx('test', priceUpdateForm.ytPrice, 'UpdateYTPriceFeed');
    writeContract({
      address: CONTRACTS.YT_PRICE_FEED, abi: YT_PRICE_FEED_ABI, functionName: 'forceUpdatePrice',
      args: [selectedVault.address as `0x${string}`, ytPrice],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleSetHardCap = () => {
    if (!hardCapForm) return;
    recordTx('test', hardCapForm, 'SetHardCap');
    writeContract({
      address: CONTRACTS.FACTORY, abi: FACTORY_ABI, functionName: 'setHardCap',
      args: [selectedVault.address as `0x${string}`, parseUnits(hardCapForm, TOKEN_DECIMALS.YT)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleSetRedemptionTime = () => {
    if (!redemptionTimeForm) return;
    const timestamp = BigInt(Math.floor(new Date(redemptionTimeForm).getTime() / 1000));
    recordTx('test', redemptionTimeForm, 'SetRedemptionTime');
    writeContract({
      address: CONTRACTS.FACTORY, abi: FACTORY_ABI, functionName: 'setVaultNextRedemptionTime',
      args: [selectedVault.address as `0x${string}`, timestamp],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleSetManager = () => {
    if (!managerForm) return;
    recordTx('test', managerForm.slice(0, 10) + '...', 'SetManager');
    writeContract({
      address: CONTRACTS.FACTORY, abi: FACTORY_ABI, functionName: 'setVaultManager',
      args: [selectedVault.address as `0x${string}`, managerForm as `0x${string}`],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  // ===== Manager 资产管理 =====
  const handleManagerApproveUsdc = () => {
    if (!depositManagedAmount) return;
    recordTx('approve', depositManagedAmount, 'USDC');
    writeContract({
      address: CONTRACTS.USDC, abi: USDC_ABI, functionName: 'approve',
      args: [selectedVault.address as `0x${string}`, parseUnits(depositManagedAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.SIMPLE,
    });
  };

  const handleDepositManagedAssets = () => {
    if (!depositManagedAmount) return;
    recordTx('test', depositManagedAmount, 'DepositManaged');
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'depositManagedAssets',
      args: [parseUnits(depositManagedAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleWithdrawForManagement = () => {
    if (!withdrawManagedAmount) return;
    const toAddress = withdrawToAddress || address;
    recordTx('test', withdrawManagedAmount, 'WithdrawManaged');
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'withdrawForManagement',
      args: [toAddress as `0x${string}`, parseUnits(withdrawManagedAmount, TOKEN_DECIMALS.USDC)],
      gas: GAS_CONFIG.STANDARD,
    });
  };

  const handleProcessBatchWithdrawals = () => {
    if (!batchSize) return;
    const size = parseInt(batchSize, 10);
    if (isNaN(size) || size <= 0) return;
    recordTx('test', batchSize, 'ProcessBatch');
    writeContract({
      address: selectedVault.address as `0x${string}`, abi: VAULT_ABI, functionName: 'processBatchWithdrawals',
      args: [BigInt(size)],
      gas: GAS_CONFIG.COMPLEX,
    });
  };

  // ===== 边界测试 =====
  const runBoundaryTest = (testType: string) => {
    setTestResult({ type: 'pending', msg: '测试运行中...' });
    setIsTestRunning(true);
    testTypeRef.current = testType;
    recordTx('test', undefined, testType);
    const vi = vaultInfo as any;
    switch (testType) {
      case 'buy_zero':
        break;
      case 'sell_zero':
        break;
      case 'buy_exceed_balance': {
        const exceedBuy = usdcBalance ? (usdcBalance as bigint) + parseUnits('999999', TOKEN_DECIMALS.USDC) : parseUnits('999999999', TOKEN_DECIMALS.USDC);
        break;
      }
      case 'sell_exceed_balance': {
        const exceedSell = ytBalance ? (ytBalance as bigint) + parseUnits('999999', TOKEN_DECIMALS.YT) : parseUnits('999999999', TOKEN_DECIMALS.YT);
        break;
      }
      case 'buy_exceed_hardcap': {
        const totalSupplyBuy = vi ? vi[3] as bigint : 0n;
        const hardCap = vi ? vi[4] as bigint : parseUnits('10000000', TOKEN_DECIMALS.YT);
        const ytPriceBuy = vi ? vi[6] as bigint : parseUnits('1', TOKEN_DECIMALS.INTERNAL_PRICE);
        const usdcPriceBuy = vi ? vi[5] as bigint : parseUnits('1', TOKEN_DECIMALS.CHAINLINK_PRICE);
        const remainingYT = hardCap > totalSupplyBuy ? hardCap - totalSupplyBuy : 0n;
        const PRECISION_ADJUSTMENT = BigInt(10) ** 34n;
        const remainingUSDC = usdcPriceBuy > 0n ? (remainingYT * ytPriceBuy) / usdcPriceBuy / PRECISION_ADJUSTMENT : 0n;
        const exceedHardcapAmount = remainingUSDC + parseUnits('100', TOKEN_DECIMALS.USDC);
        break;
      }
      case 'sell_in_lock':
        break;
      case 'max_approve':
        break;
    }
  };

  // ===== 显示值计算 =====
  // getVaultInfo 索引: [0]=totalAssets(USDC), [1]=idleAssets(USDC), [2]=managedAssets(USDC),
  //                   [3]=totalSupply(YT), [4]=hardCap(YT), [5]=usdcPrice(8dec), [6]=ytPrice(30dec)
  const vi = vaultInfo as any;
  const totalAssetsValue = vi?.[0] ? Number(formatUnits(vi[0], TOKEN_DECIMALS.USDC)) : 0;
  const idleAssetsValue = vi?.[1] ? Number(formatUnits(vi[1], TOKEN_DECIMALS.USDC)) : 0;
  const managedAssetsValue = vi?.[2] ? Number(formatUnits(vi[2], TOKEN_DECIMALS.USDC)) : 0;
  const totalSupplyValue = vi?.[3] ? Number(formatUnits(vi[3], TOKEN_DECIMALS.YT)) : 0;
  const hardCapValue = vi?.[4] ? Number(formatUnits(vi[4], TOKEN_DECIMALS.YT)) : 0;
  const ytPriceValue = vi?.[6] ? Number(formatUnits(vi[6], TOKEN_DECIMALS.INTERNAL_PRICE)) : 0;
  const ytBalanceValue = ytBalance ? Number(formatUnits(ytBalance as bigint, TOKEN_DECIMALS.YT)) : 0;
  const usdcBalanceValue = usdcBalance ? Number(formatUnits(usdcBalance as bigint, TOKEN_DECIMALS.USDC)) : 0;
  const needsApproval = !usdcAllowance || (usdcAllowance as bigint) < parseUnits(buyAmount || '0', TOKEN_DECIMALS.USDC);

  if (!isConnected) {
    return (
      <PageContainer>
        <ProCard>
          <Space direction="vertical" size="large" style={{ width: '100%', textAlign: 'center', padding: '40px 0' }}>
            <WalletOutlined style={{ fontSize: 64, color: '#bbb' }} />
            <Text type="secondary">{intl.formatMessage({ id: 'pages.common.connectFirst' })}</Text>
          </Space>
        </ProCard>
      </PageContainer>
    );
  }

  // ===== 渲染 =====
  return (
    <PageContainer title={`${intl.formatMessage({ id: 'pages.vault.title' })} (${currentChainName})`}>
      <Space direction="vertical" size="large" style={{ width: '100%' }}>

        {/* 金库选择 */}
        <ProCard title={intl.formatMessage({ id: 'pages.vault.selectVault' })}>
          <Select
            size="large"
            style={{ width: '100%' }}
            value={selectedVault.address}
            onChange={(value) => {
              const vault = vaultList.find(v => v.address === value);
              if (vault) setSelectedVault(vault);
            }}
            options={vaultList.map(v => ({ label: `${v.name}: ${v.address}`, value: v.address }))}
          />
        </ProCard>

        {/* 合约信息 & 角色 */}
        <ProCard
          title={<span><InfoCircleOutlined style={{ marginRight: 8 }} />合约信息</span>}
          size="small"
          collapsible
          defaultCollapsed={false}
        >
          <Descriptions size="small" column={{ xs: 1, sm: 2, md: 2 }} bordered>
            <Descriptions.Item label="金库名称">
              {vaultName as string || '-'} ({vaultSymbol as string || '-'})
            </Descriptions.Item>
            <Descriptions.Item label="当前角色">
              <Tag color={isOwner ? 'gold' : isManager ? 'blue' : 'default'}>
                {currentRole}
              </Tag>
            </Descriptions.Item>
            <Descriptions.Item label="金库地址">
              <Space>
                <Text code style={{ fontSize: 14 }}>{selectedVault.address}</Text>
                <Button size="small" icon={<CopyOutlined />} onClick={() => copyToClipboard(selectedVault.address)} />
              </Space>
            </Descriptions.Item>
            <Descriptions.Item label="Factory Owner">
              <Space>
                <Text code style={{ fontSize: 14 }}>
                  {factoryOwner ? `${(factoryOwner as string).slice(0, 10)}...${(factoryOwner as string).slice(-6)}` : '-'}
                </Text>
                {isOwner && <Tag color="gold">你</Tag>}
              </Space>
            </Descriptions.Item>
            <Descriptions.Item label="工厂合约">
              <Text code style={{ fontSize: 14 }}>
                {vaultFactory ? `${(vaultFactory as string).slice(0, 10)}...${(vaultFactory as string).slice(-6)}` : '-'}
              </Text>
            </Descriptions.Item>
            <Descriptions.Item label="Vault Manager">
              <Space>
                <Text code style={{ fontSize: 14 }}>
                  {vaultManager ? `${(vaultManager as string).slice(0, 10)}...${(vaultManager as string).slice(-6)}` : '-'}
                </Text>
                {isManager && <Tag color="blue">你</Tag>}
              </Space>
            </Descriptions.Item>
            <Descriptions.Item label="USDC 合约">
              <Text code style={{ fontSize: 14 }}>
                {vaultUsdcAddress ? `${(vaultUsdcAddress as string).slice(0, 10)}...${(vaultUsdcAddress as string).slice(-6)}` : '-'}
              </Text>
            </Descriptions.Item>
            <Descriptions.Item label="价格精度">
              {pricePrecision ? (pricePrecision as bigint).toString() : '-'}
            </Descriptions.Item>
          </Descriptions>
        </ProCard>

        {/* 金库统计 */}
        <Row gutter={[16, 16]}>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard statistic={{ title: '总资产', value: totalAssetsValue, precision: 2, suffix: 'USDC' }} />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard statistic={{ title: '闲置资产', value: idleAssetsValue, precision: 2, suffix: 'USDC' }} />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard statistic={{ title: intl.formatMessage({ id: 'pages.vault.totalSupply' }), value: totalSupplyValue, precision: 2, suffix: vaultSymbol as string }} />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard statistic={{ title: intl.formatMessage({ id: 'pages.vault.hardCap' }), value: hardCapValue, precision: 2, suffix: vaultSymbol as string }} />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard statistic={{ title: intl.formatMessage({ id: 'pages.vault.ytPrice' }), value: ytPriceValue, precision: 6, suffix: 'USDC' }} />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <StatisticCard
              style={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}
              statistic={{
                title: <span style={{ color: 'rgba(255,255,255,0.9)' }}>{intl.formatMessage({ id: 'pages.vault.yourBalance' })}</span>,
                value: ytBalanceValue,
                precision: 2,
                suffix: <span style={{ color: 'white' }}>{vaultSymbol as string}</span>,
                valueStyle: { color: 'white' },
              }}
            />
          </Col>
        </Row>

        {/* 交易面板 */}
        <ProCard>
          <Tabs
            activeKey={activeTab}
            onChange={setActiveTab}
            items={[
              {
                key: 'buy',
                label: <span><ShoppingCartOutlined /> {intl.formatMessage({ id: 'pages.vault.buy' })}</span>,
                children: (
                  <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                    {isAtHardCap && (
                      <Alert
                        type="warning"
                        showIcon
                        icon={<WarningOutlined />}
                        message="金库已达硬顶，无法直接购买，请使用下方 LP Swap 获取"
                      />
                    )}
                    <div>
                      <Text strong>{intl.formatMessage({ id: 'pages.vault.buyAmount' })} (USDC)</Text>
                      <Input
                        size="large"
                        type="number"
                        value={buyAmount}
                        onChange={(e) => setBuyAmount(e.target.value)}
                        placeholder={intl.formatMessage({ id: 'pages.vault.enterAmount' })}
                        suffix={<Text type="secondary">余额: {usdcBalanceValue.toFixed(2)} USDC</Text>}
                        style={{ marginTop: 8 }}
                        disabled={isAtHardCap}
                      />
                    </div>
                    {previewBuyAmount && (
                      <div style={{ background: '#f5f5f5', border: '1px solid #e0e0e0', borderRadius: 6, padding: '10px 12px', fontSize: 14 }}>
                        <div>
                          <span style={{ color: '#666' }}>{intl.formatMessage({ id: 'pages.vault.youWillReceive' })}: </span>
                          <strong style={{ color: '#333' }}>{formatUnits(previewBuyAmount as bigint, TOKEN_DECIMALS.YT)} {vaultSymbol}</strong>
                        </div>
                        <div style={{ marginTop: 4, color: '#888', fontSize: 13 }}>
                          授权额度: {usdcAllowance !== undefined ? formatUnits(usdcAllowance as bigint, TOKEN_DECIMALS.USDC) : 'loading...'} USDC
                          {buyAmount && ` | 需要: ${buyAmount} | 需授权: ${needsApproval ? '是' : '否'}`}
                        </div>
                        <div style={{ marginTop: 4, color: '#999', fontSize: 12, fontFamily: 'monospace' }}>
                          previewBuy 原始值: {(previewBuyAmount as bigint).toString()}
                          {vi?.[6] && (<><br />ytPrice: {(vi[6] as bigint).toString()} (显示: {formatUnits(vi[6] as bigint, TOKEN_DECIMALS.INTERNAL_PRICE)})</>)}
                          {vi?.[5] && (<><br />usdcPrice: {(vi[5] as bigint).toString()} (显示: {formatUnits(vi[5] as bigint, TOKEN_DECIMALS.CHAINLINK_PRICE)})</>)}
                          {pricePrecision && (<><br />PRICE_PRECISION: {(pricePrecision as bigint).toString()}</>)}
                        </div>
                      </div>
                    )}
                    {!isAtHardCap && (needsApproval ? (
                      <Button type="primary" size="large" onClick={handleApprove} loading={isProcessing} disabled={isProcessing} block>
                        {intl.formatMessage({ id: 'pages.vault.approve' })} USDC
                      </Button>
                    ) : (
                      <Button type="primary" size="large" icon={<ShoppingCartOutlined />} onClick={handleBuy} loading={isProcessing} disabled={isProcessing || !buyAmount} block>
                        {intl.formatMessage({ id: 'pages.vault.buy' })}
                      </Button>
                    ))}

                    {/* 硬顶 Swap */}
                    <Collapse
                      style={{ marginTop: 8 }}
                      items={[{
                        key: 'hardcap-swap',
                        label: (
                          <span>
                            <SwapOutlined style={{ marginRight: 6 }} />
                            {isAtHardCap ? '🔴 金库已达硬顶 — LP Swap 获取 YT' : 'LP 硬顶 Swap (USDC → YT)'}
                          </span>
                        ),
                        children: (
                          <Space direction="vertical" size="small" style={{ width: '100%' }}>
                            {/* LP 状态 */}
                            <div style={{ padding: '8px 12px', background: '#fafafa', borderRadius: 6, fontSize: 13 }}>
                              <Space wrap size={16}>
                                <span>LP Swap: <Tag color={lpSwapEnabled ? 'green' : 'red'}>{lpSwapEnabled ? '开启' : '关闭'}</Tag></span>
                                <span>USDC 白名单: <Tag color={usdcWhitelisted ? 'green' : 'red'}>{usdcWhitelisted ? '✓' : '✗'}</Tag></span>
                                <span>{selectedVault.name} 白名单: <Tag color={targetYtWhitelisted ? 'green' : 'red'}>{targetYtWhitelisted ? '✓' : '✗'}</Tag></span>
                                <span>YT 池余额: <strong>{targetYtPoolAmount !== undefined ? Number(formatUnits(targetYtPoolAmount as bigint, TOKEN_DECIMALS.YT)).toFixed(4) : '...'}</strong></span>
                              </Space>
                              <Space wrap size={16} style={{ marginTop: 4 }}>
                                <span>Router 授权: <Text type={needsHardcapSwapApproval ? 'danger' : 'success'}>{usdcRouterAllowance !== undefined ? Number(formatUnits(usdcRouterAllowance as bigint, TOKEN_DECIMALS.USDC)).toFixed(2) : '...'}</Text></span>
                                <span>Vault 授权: <Text type={needsVaultApproval ? 'danger' : 'success'}>{usdcVaultAllowance !== undefined ? Number(formatUnits(usdcVaultAllowance as bigint, TOKEN_DECIMALS.USDC)).toFixed(2) : '...'}</Text></span>
                                <span>USDC 价格: <Text>{usdcMinPrice ? Number(formatUnits(usdcMinPrice as bigint, TOKEN_DECIMALS.INTERNAL_PRICE)).toFixed(6) : '0'}</Text></span>
                                <span>{selectedVault.name} 价格: <Text>{targetYtMaxPrice ? Number(formatUnits(targetYtMaxPrice as bigint, TOKEN_DECIMALS.INTERNAL_PRICE)).toFixed(6) : '0'}</Text></span>
                              </Space>
                            </div>
                            <div style={{ display: 'flex', gap: 8 }}>
                              <Input
                                type="number"
                                value={hardcapSwapAmount}
                                onChange={(e) => setHardcapSwapAmount(e.target.value)}
                                placeholder="USDC 数量"
                                suffix="USDC"
                                style={{ flex: 3 }}
                              />
                              <Input
                                type="number"
                                value={hardcapSwapSlippage}
                                onChange={(e) => setHardcapSwapSlippage(e.target.value)}
                                placeholder="0.5"
                                suffix="% 滑点"
                                step="0.1"
                                style={{ flex: 1 }}
                              />
                            </div>
                            {hardcapSwapAmount && hardcapSwapPreview && (
                              <Alert
                                message={`预计获得: ${Number(formatUnits(hardcapSwapPreview as bigint, TOKEN_DECIMALS.YT)).toFixed(6)} ${selectedVault.name}`}
                                type="info"
                                showIcon
                              />
                            )}
                            <Space>
                              {needsHardcapSwapApproval && (
                                <Button onClick={handleApproveUsdcForRouter} loading={isProcessing} disabled={!hardcapSwapAmount}>
                                  授权 Router
                                </Button>
                              )}
                              {needsVaultApproval && (
                                <Button onClick={handleApproveUsdcForVault} loading={isProcessing} disabled={!hardcapSwapAmount}>
                                  授权 Vault
                                </Button>
                              )}
                              {!needsHardcapSwapApproval && !needsVaultApproval && (
                                <Button
                                  type="primary"
                                  icon={<SwapOutlined />}
                                  onClick={handleHardcapSwap}
                                  loading={isProcessing}
                                  disabled={!hardcapSwapAmount || !lpSwapEnabled || !usdcWhitelisted || !targetYtWhitelisted}
                                >
                                  Swap 获取 {selectedVault.name}
                                </Button>
                              )}
                            </Space>
                          </Space>
                        ),
                      }]}
                    />
                  </Space>
                ),
              },
              {
                key: 'sell',
                label: <span><DollarOutlined /> {intl.formatMessage({ id: 'pages.vault.sell' })}</span>,
                children: (
                  <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                    {/* 赎回状态 */}
                    <Alert
                      type={canRedeem ? 'success' : 'warning'}
                      showIcon
                      message={
                        <Space>
                          <span>赎回状态: <strong>{canRedeem ? '✅ 可以赎回' : '⏳ 锁定中'}</strong></span>
                          {!canRedeem && countdown > 0 && (
                            <span>距下次赎回: <strong>{formatTimeRemaining(countdown)}</strong></span>
                          )}
                        </Space>
                      }
                    />

                    {/* 队列进度 */}
                    {queueProgress && (
                      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, padding: '12px 16px', background: '#f8f9fa', borderRadius: 8, fontSize: 14 }}>
                        <div><Text type="secondary">队列总数: </Text><strong>{(queueProgress as any)[1]?.toString() || '0'}</strong></div>
                        <div><Text type="secondary">待处理: </Text><strong style={{ color: Number((queueProgress as any)[2]) > 0 ? '#e65100' : undefined }}>{(queueProgress as any)[2]?.toString() || '0'}</strong></div>
                        <div><Text type="secondary">已处理: </Text><strong>{(queueProgress as any)[0]?.toString() || '0'}</strong></div>
                      </div>
                    )}

                    <div>
                      <Text strong>{intl.formatMessage({ id: 'pages.vault.sellAmount' })} ({vaultSymbol as string})</Text>
                      <Input
                        size="large"
                        type="number"
                        value={sellAmount}
                        onChange={(e) => setSellAmount(e.target.value)}
                        placeholder={intl.formatMessage({ id: 'pages.vault.enterAmount' })}
                        suffix={<Text type="secondary">余额: {ytBalanceValue.toFixed(4)} {vaultSymbol as string}</Text>}
                        style={{ marginTop: 8 }}
                        disabled={!canRedeem}
                      />
                    </div>
                    {previewSellAmount && (
                      <Alert
                        message={`${intl.formatMessage({ id: 'pages.vault.youWillReceive' })}: ${Number(formatUnits(previewSellAmount as bigint, TOKEN_DECIMALS.USDC)).toFixed(6)} USDC`}
                        type="info"
                      />
                    )}
                    <Button
                      type="primary"
                      size="large"
                      icon={<DollarOutlined />}
                      onClick={handleSell}
                      loading={isProcessing}
                      disabled={isProcessing || !sellAmount || !canRedeem}
                      block
                    >
                      {!canRedeem ? '🔒 赎回锁定中' : intl.formatMessage({ id: 'pages.vault.sell' })}
                    </Button>

                    {/* 我的待处理请求 */}
                    {userPendingRequests && (userPendingRequests as any[]).length > 0 && (
                      <div>
                        <Text strong style={{ display: 'block', marginBottom: 8 }}>我的待处理退出请求</Text>
                        <Table
                          size="small"
                          pagination={false}
                          dataSource={(userPendingRequests as any[]).map((req, idx) => ({ key: idx, ...req }))}
                          columns={[
                            { title: 'YT 数量', dataIndex: 'ytAmount', render: (v: bigint) => Number(formatUnits(v, TOKEN_DECIMALS.YT)).toFixed(4) },
                            { title: 'USDC 数量', dataIndex: 'usdcAmount', render: (v: bigint) => Number(formatUnits(v, TOKEN_DECIMALS.USDC)).toFixed(4) },
                            { title: '请求时间', dataIndex: 'requestTime', render: (v: bigint) => new Date(Number(v) * 1000).toLocaleString() },
                            { title: '状态', dataIndex: 'processed', render: (v: boolean) => <Tag color={v ? 'default' : 'orange'}>{v ? '已处理' : '待处理'}</Tag> },
                          ]}
                        />
                      </div>
                    )}
                  </Space>
                ),
              },
              {
                key: 'transfer',
                label: <span><SendOutlined /> {intl.formatMessage({ id: 'pages.vault.transfer' })}</span>,
                children: (
                  <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                    <div>
                      <Text strong>{intl.formatMessage({ id: 'pages.usdc.toAddress' })}</Text>
                      <Input
                        size="large"
                        value={transferYtTo}
                        onChange={(e) => setTransferYtTo(e.target.value)}
                        placeholder="0x..."
                        style={{ marginTop: 8 }}
                      />
                    </div>
                    <div>
                      <Text strong>{intl.formatMessage({ id: 'pages.usdc.transferAmount' })} ({vaultSymbol as string})</Text>
                      <Input
                        size="large"
                        type="number"
                        value={transferYtAmount}
                        onChange={(e) => setTransferYtAmount(e.target.value)}
                        placeholder={intl.formatMessage({ id: 'pages.vault.enterAmount' })}
                        suffix={<Text type="secondary">余额: {ytBalanceValue.toFixed(4)} {vaultSymbol as string}</Text>}
                        style={{ marginTop: 8 }}
                      />
                    </div>
                    <Button
                      type="primary"
                      size="large"
                      icon={<SendOutlined />}
                      onClick={handleTransferYt}
                      loading={isProcessing}
                      disabled={isProcessing || !transferYtTo || !transferYtAmount}
                      block
                    >
                      {intl.formatMessage({ id: 'pages.vault.transfer' })}
                    </Button>
                  </Space>
                ),
              },
            ]}
          />
        </ProCard>

        {/* 管理面板 Collapse */}
        <Collapse
          items={[
            {
              key: 'admin',
              label: <span><SettingOutlined style={{ marginRight: 8 }} />管理员配置 (Factory Owner)</span>,
              children: (
                <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                  <Alert
                    type={isOwner ? 'success' : 'info'}
                    message={
                      <Space>
                        <span>Factory Owner: <Text code>{factoryOwner as string || '-'}</Text></span>
                        {isOwner ? <Tag color="gold">你是 Owner</Tag> : <Tag>你不是 Owner</Tag>}
                      </Space>
                    }
                  />

                  {/* 更新 YT 价格 */}
                  <ProCard title="更新 YT 价格" size="small" bordered>
                    <Space direction="vertical" style={{ width: '100%' }} size="small">
                      <div style={{ fontSize: 13, color: '#888' }}>
                        <span>当前价格: {vi?.[6] ? Number(formatUnits(vi[6], TOKEN_DECIMALS.INTERNAL_PRICE)).toFixed(6) : '-'} (30位精度)</span>
                        {ytLastPrice && <span style={{ marginLeft: 16 }}>预言机上次: {Number(formatUnits(ytLastPrice as bigint, TOKEN_DECIMALS.INTERNAL_PRICE)).toFixed(6)}</span>}
                        {maxPriceChangeBps && <span style={{ marginLeft: 16 }}>允许最大变化: {(Number(maxPriceChangeBps as bigint) / 100).toFixed(2)}%</span>}
                      </div>
                      {priceWarning && (
                        <Alert type="warning" showIcon message={priceWarning.message} />
                      )}
                      <div style={{ display: 'flex', gap: 8 }}>
                        <Input
                          value={priceUpdateForm.ytPrice}
                          onChange={(e) => setPriceUpdateForm({ ytPrice: e.target.value })}
                          placeholder="YT 价格 (如: 1.05)"
                          type="number"
                          step="0.01"
                          style={{ flex: 1 }}
                        />
                        <Button type="primary" onClick={handleUpdatePrices} loading={isProcessing} disabled={!isOwner}>
                          更新金库价格
                        </Button>
                        <Button onClick={handleUpdateYTPriceFeed} loading={isProcessing} disabled={!isOwner || !CONTRACTS.YT_PRICE_FEED} title="更新 YTPriceFeed 预言机">
                          更新预言机
                        </Button>
                      </div>
                      <Text type="secondary" style={{ fontSize: 14 }}>
                        提示: 先点"更新金库价格"，成功后再点"更新预言机"同步价格
                      </Text>
                    </Space>
                  </ProCard>

                  {/* 设置硬顶 */}
                  <ProCard title="设置硬顶" size="small" bordered>
                    <div style={{ display: 'flex', gap: 8 }}>
                      <Input
                        value={hardCapForm}
                        onChange={(e) => setHardCapForm(e.target.value)}
                        placeholder={`新硬顶 (当前: ${hardCapValue.toFixed(2)} ${vaultSymbol})`}
                        type="number"
                        style={{ flex: 1 }}
                      />
                      <Button onClick={handleSetHardCap} loading={isProcessing} disabled={!hardCapForm || !isOwner}>
                        设置硬顶
                      </Button>
                    </div>
                  </ProCard>

                  {/* 设置赎回时间 */}
                  <ProCard title="设置赎回时间" size="small" bordered>
                    <div style={{ display: 'flex', gap: 8 }}>
                      <DatePicker
                        showTime
                        style={{ flex: 1 }}
                        value={redemptionTimeForm ? dayjs(redemptionTimeForm) : null}
                        onChange={(date) => setRedemptionTimeForm(date ? date.toISOString() : '')}
                      />
                      <Button onClick={handleSetRedemptionTime} loading={isProcessing} disabled={!redemptionTimeForm || !isOwner}>
                        设置时间
                      </Button>
                    </div>
                  </ProCard>

                  {/* 设置管理员 */}
                  <ProCard title="设置 Vault Manager" size="small" bordered>
                    <div style={{ display: 'flex', gap: 8 }}>
                      <Input
                        value={managerForm}
                        onChange={(e) => setManagerForm(e.target.value)}
                        placeholder={`新管理员地址 (当前: ${vaultManager ? (vaultManager as string).slice(0, 10) + '...' : '-'})`}
                        style={{ flex: 1 }}
                      />
                      <Button onClick={handleSetManager} loading={isProcessing} disabled={!managerForm || !isOwner}>
                        设置管理员
                      </Button>
                    </div>
                  </ProCard>

                  {/* 批量处理退出请求 */}
                  <ProCard title="批量处理退出请求" size="small" bordered>
                    <Space direction="vertical" style={{ width: '100%' }} size="small">
                      {queueProgress && (
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, fontSize: 14 }}>
                          <div><Text type="secondary">总计: </Text><strong>{(queueProgress as any)[1]?.toString() || '0'}</strong></div>
                          <div><Text type="secondary">待处理: </Text><strong style={{ color: Number((queueProgress as any)[2]) > 0 ? '#e65100' : undefined }}>{(queueProgress as any)[2]?.toString() || '0'}</strong></div>
                          <div><Text type="secondary">已处理: </Text><strong>{(queueProgress as any)[0]?.toString() || '0'}</strong></div>
                        </div>
                      )}
                      {pendingRequestsList.length > 0 && (
                        <Table
                          size="small"
                          pagination={false}
                          scroll={{ y: 200 }}
                          dataSource={pendingRequestsList.map(r => ({ key: r.requestId, ...r }))}
                          columns={[
                            { title: 'ID', dataIndex: 'requestId', width: 60, render: (v: number) => `#${v}` },
                            { title: '用户', dataIndex: 'user', render: (v: string) => <Text code style={{ fontSize: 11 }}>{v.slice(0, 8)}...{v.slice(-6)}</Text> },
                            { title: 'YT 数量', dataIndex: 'ytAmount', align: 'right', render: (v: bigint) => Number(formatUnits(v, TOKEN_DECIMALS.YT)).toFixed(4) },
                            { title: 'USDC 数量', dataIndex: 'usdcAmount', align: 'right', render: (v: bigint) => <strong>{Number(formatUnits(v, TOKEN_DECIMALS.USDC)).toFixed(4)}</strong> },
                            { title: '请求时间', dataIndex: 'requestTime', render: (v: bigint) => new Date(Number(v) * 1000).toLocaleString() },
                          ]}
                          summary={() => pendingRequestsList.length > 0 ? (
                            <Table.Summary.Row>
                              <Table.Summary.Cell index={0} colSpan={2}><strong>合计</strong></Table.Summary.Cell>
                              <Table.Summary.Cell index={2} align="right"><strong>{Number(formatUnits(pendingRequestsList.reduce((s, r) => s + r.ytAmount, 0n), TOKEN_DECIMALS.YT)).toFixed(4)}</strong></Table.Summary.Cell>
                              <Table.Summary.Cell index={3} align="right"><strong style={{ color: '#e65100' }}>{Number(formatUnits(pendingRequestsList.reduce((s, r) => s + r.usdcAmount, 0n), TOKEN_DECIMALS.USDC)).toFixed(4)}</strong></Table.Summary.Cell>
                              <Table.Summary.Cell index={4} />
                            </Table.Summary.Row>
                          ) : null}
                        />
                      )}
                      <div style={{ display: 'flex', gap: 8 }}>
                        <Input
                          type="number"
                          value={batchSize}
                          onChange={(e) => setBatchSize(e.target.value)}
                          placeholder="批量大小"
                          min={1}
                          max={100}
                          style={{ width: 120 }}
                        />
                        <Button
                          type="primary"
                          onClick={handleProcessBatchWithdrawals}
                          loading={isProcessing}
                          disabled={!batchSize || !isOwner && !isManager || (queueProgress && (queueProgress as any)[2]?.toString() === '0')}
                        >
                          批量处理退出
                        </Button>
                      </div>
                      <Text type="secondary" style={{ fontSize: 14 }}>Owner 或 Manager 可执行此操作</Text>
                    </Space>
                  </ProCard>
                </Space>
              ),
            },
            {
              key: 'manager',
              label: <span><UserOutlined style={{ marginRight: 8 }} />Manager 资产管理</span>,
              children: (
                <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                  <Alert
                    type={isManager ? 'success' : 'info'}
                    message={
                      <Space>
                        <span>Vault Manager: <Text code>{vaultManager as string || '-'}</Text></span>
                        {isManager ? <Tag color="blue">你是 Manager</Tag> : <Tag>你不是 Manager</Tag>}
                      </Space>
                    }
                  />

                  {/* 资产概览 */}
                  <Row gutter={[12, 12]}>
                    <Col span={8}>
                      <div style={{ padding: '12px 16px', background: '#f8f9fa', borderRadius: 8, textAlign: 'center' }}>
                        <div style={{ fontSize: 14, color: '#888' }}>总资产</div>
                        <strong style={{ fontSize: 16 }}>{totalAssetsValue.toFixed(4)} USDC</strong>
                      </div>
                    </Col>
                    <Col span={8}>
                      <div style={{ padding: '12px 16px', background: '#f8f9fa', borderRadius: 8, textAlign: 'center' }}>
                        <div style={{ fontSize: 14, color: '#888' }}>闲置资产</div>
                        <strong style={{ fontSize: 16 }}>{idleAssetsValue.toFixed(4)} USDC</strong>
                      </div>
                    </Col>
                    <Col span={8}>
                      <div style={{ padding: '12px 16px', background: '#f8f9fa', borderRadius: 8, textAlign: 'center' }}>
                        <div style={{ fontSize: 14, color: '#888' }}>托管资产</div>
                        <strong style={{ fontSize: 16 }}>{managedAssetsValue.toFixed(4)} USDC</strong>
                      </div>
                    </Col>
                  </Row>

                  {/* 存入托管资产 */}
                  <ProCard title="存入托管资产 (depositManagedAssets)" size="small" bordered>
                    <Space direction="vertical" style={{ width: '100%' }} size="small">
                      <Text type="secondary" style={{ fontSize: 14 }}>
                        已授权: {managerUsdcAllowance !== undefined ? Number(formatUnits(managerUsdcAllowance as bigint, TOKEN_DECIMALS.USDC)).toFixed(4) : '...'} USDC
                        {depositManagedAmount && ` | 需授权: ${managerNeedsApproval ? '是' : '否'}`}
                      </Text>
                      <div style={{ display: 'flex', gap: 8 }}>
                        <Input
                          type="number"
                          value={depositManagedAmount}
                          onChange={(e) => setDepositManagedAmount(e.target.value)}
                          placeholder="USDC 数量"
                          style={{ flex: 1 }}
                        />
                        {managerNeedsApproval ? (
                          <Button onClick={handleManagerApproveUsdc} loading={isProcessing} disabled={!depositManagedAmount || !isManager}>
                            授权 USDC
                          </Button>
                        ) : (
                          <Button type="primary" onClick={handleDepositManagedAssets} loading={isProcessing} disabled={!depositManagedAmount || !isManager}>
                            存入
                          </Button>
                        )}
                      </div>
                    </Space>
                  </ProCard>

                  {/* 提取托管资产 */}
                  <ProCard title="提取托管资产 (withdrawForManagement)" size="small" bordered>
                    <Space direction="vertical" style={{ width: '100%' }} size="small">
                      <div style={{ display: 'flex', gap: 8 }}>
                        <Input
                          type="number"
                          value={withdrawManagedAmount}
                          onChange={(e) => setWithdrawManagedAmount(e.target.value)}
                          placeholder="USDC 数量"
                          style={{ flex: 1 }}
                        />
                        <Input
                          value={withdrawToAddress}
                          onChange={(e) => setWithdrawToAddress(e.target.value)}
                          placeholder="接收地址 (默认自己)"
                          style={{ flex: 2 }}
                        />
                        <Button onClick={handleWithdrawForManagement} loading={isProcessing} disabled={!withdrawManagedAmount || !isManager}>
                          提取
                        </Button>
                      </div>
                    </Space>
                  </ProCard>
                </Space>
              ),
            },
            {
              key: 'boundary',
              label: <span><SafetyOutlined style={{ marginRight: 8 }} />边界测试</span>,
              children: (
                <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                  <Alert
                    type="info"
                    showIcon
                    message="以下测试预期会失败 (合约应拒绝这些操作)，用于验证合约安全性"
                  />
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', padding: '8px 12px', background: '#f8f9fa', borderRadius: 8, fontSize: 14 }}>
                    <span>赎回状态: <Tag color={canRedeem ? 'green' : 'orange'}>{canRedeem ? '可赎回' : '锁定中'}</Tag></span>
                    {!canRedeem && countdown > 0 && <span>距下次: <strong>{formatTimeRemaining(countdown)}</strong></span>}
                  </div>
                  <Row gutter={[12, 12]}>
                    {[
                      { key: 'buy_zero', name: '买入 0 数量', error: 'InvalidAmount', desc: '预期: 买入 0 USDC 应失败' },
                      { key: 'sell_zero', name: '卖出 0 数量', error: 'InvalidAmount', desc: '预期: 卖出 0 YT 应失败' },
                      { key: 'buy_exceed_balance', name: '超余额买入', error: 'InsufficientUSDC', desc: '预期: 买入超过 USDC 余额应失败' },
                      { key: 'sell_exceed_balance', name: '超余额卖出', error: 'InsufficientYT', desc: '预期: 卖出超过 YT 余额应失败' },
                      { key: 'buy_exceed_hardcap', name: '超硬顶买入', error: 'HardCapExceeded', desc: '预期: 买入超过硬顶应失败' },
                      { key: 'sell_in_lock', name: '锁定期卖出', error: 'StillInLockPeriod', desc: '预期: 在锁定期卖出应失败' },
                      { key: 'max_approve', name: 'MaxUint256 授权', error: 'MaxUint256', desc: '预期: 最大授权应成功' },
                    ].map(test => (
                      <Col key={test.key} xs={24} sm={12} md={8}>
                        <div style={{ padding: '12px 16px', border: '1px solid #f0f0f0', borderRadius: 8, background: '#fff' }}>
                          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 6 }}>
                            <div>
                              <div style={{ fontSize: 14, fontWeight: 500 }}>{test.name}</div>
                              <Tag color="red" style={{ marginTop: 4 }}>{test.error}</Tag>
                            </div>
                            <Button
                              size="small"
                              onClick={() => runBoundaryTest(test.key)}
                              loading={isTestRunning && testTypeRef.current === test.key}
                              disabled={isProcessing}
                            >
                              测试
                            </Button>
                          </div>
                          <div style={{ fontSize: 14, color: '#888' }}>{test.desc}</div>
                        </div>
                      </Col>
                    ))}
                  </Row>
                  {testResult && (
                    <Alert
                      type={testResult.type === 'error' ? 'warning' : testResult.type === 'success' ? 'success' : 'info'}
                      showIcon
                      message={testResult.msg}
                    />
                  )}
                </Space>
              ),
            },
          ]}
        />

        {/* 交易历史 */}
        <TransactionHistory transactions={transactions} onClear={clearHistory} />
      </Space>
    </PageContainer>
  );
}
