"use client";

import Image from "next/image";
import { useEffect, useMemo } from "react";
import { useReadContracts } from 'wagmi';
import { useAccount } from 'wagmi';
import { formatUnits } from 'viem';
import { useQuery } from '@tanstack/react-query';
import { useApp } from "@/contexts/AppContext";
import { getContractAddress, abis } from '@/lib/contracts';

function formatUSD(v: number): string {
  if (v >= 1_000_000) return `$${(v / 1_000_000).toFixed(2)}M`;
  if (v >= 1_000) return `$${(v / 1_000).toFixed(2)}K`;
  return `$${v.toFixed(2)}`;
}

export default function LiquidityAllocationTable({ refreshTrigger }: { refreshTrigger?: number }) {
  const { t } = useApp();
  const { chainId } = useAccount();

  // Fetch all products from backend; filter non-stablecoins to build YT token list
  const { data: products = [] } = useQuery<any[]>({
    queryKey: ['products'],
    queryFn: async () => {
      const res = await fetch('/api/fundmarket/products?token_list=1');
      const json = await res.json();
      return json.data ?? [];
    },
    staleTime: 5 * 60 * 1000,
  });

  // Build dynamic YT token list from DB products (only yt_token role)
  // Use contractAddress and chainId directly from product data
  const ytTokens = useMemo(() =>
    products
      .filter((p: any) => p.token_role === 'yt_token' && p.contractAddress)
      .map((p: any) => ({
        key: p.tokenSymbol as string,
        address: p.contractAddress as string,
        chainId: p.chainId as number,
        meta: p,
      })),
  [products]);

  // Derive target chainId from products, fallback to connected wallet
  const targetChainId = ytTokens[0]?.chainId ?? chainId;

  // System contract addresses from registry
  const ytVaultAddr   = targetChainId ? getContractAddress('YTVault', targetChainId) : undefined;
  const usdcAddr      = targetChainId ? getContractAddress('USDC', targetChainId) : undefined;
  const priceFeedAddr = targetChainId ? getContractAddress('YTPriceFeed', targetChainId) : undefined;

  const N = ytTokens.length;
  const addressesReady = !!(ytVaultAddr && usdcAddr && priceFeedAddr && N > 0 && ytTokens.every(t => t.address));

  // Dynamic batch on-chain reads — indices scale with N = ytTokens.length:
  // [0]          YTVault.getPoolValue(true)
  // [1..N]       YTVault.usdyAmounts(ytToken[i])
  // [N+1..2N]    YTPriceFeed.getPrice(ytToken[i], false)
  // [2N+1]       USDC.balanceOf(ytVaultAddr)
  // [2N+2]       YTPriceFeed.getPrice(usdcAddr, false)
  // [2N+3]       YTVault.totalTokenWeights()
  // [2N+4..3N+3] YTVault.tokenWeights(ytToken[i])
  // [3N+4]       YTVault.tokenWeights(usdcAddr)
  const { data: chainData, refetch: refetchChain } = useReadContracts({
    contracts: [
      {
        address: ytVaultAddr,
        abi: abis.YTVault as any,
        functionName: 'getPoolValue',
        args: [true],
        chainId: targetChainId,
      } as const,
      ...ytTokens.map(tk => ({
        address: ytVaultAddr,
        abi: abis.YTVault as any,
        functionName: 'usdyAmounts',
        args: [tk.address],
        chainId: targetChainId,
      } as const)),
      ...ytTokens.map(tk => ({
        address: priceFeedAddr,
        abi: abis.YTPriceFeed as any,
        functionName: 'getPrice',
        args: [tk.address, false],
        chainId: targetChainId,
      } as const)),
      {
        address: usdcAddr,
        abi: abis.USDY as any,
        functionName: 'balanceOf',
        args: [ytVaultAddr],
        chainId: targetChainId,
      } as const,
      {
        address: priceFeedAddr,
        abi: abis.YTPriceFeed as any,
        functionName: 'getPrice',
        args: [usdcAddr, false],
        chainId: targetChainId,
      } as const,
      {
        address: ytVaultAddr,
        abi: abis.YTVault as any,
        functionName: 'totalTokenWeights',
        chainId: targetChainId,
      } as const,
      ...ytTokens.map(tk => ({
        address: ytVaultAddr,
        abi: abis.YTVault as any,
        functionName: 'tokenWeights',
        args: [tk.address],
        chainId: targetChainId,
      } as const)),
      {
        address: ytVaultAddr,
        abi: abis.YTVault as any,
        functionName: 'tokenWeights',
        args: [usdcAddr],
        chainId: targetChainId,
      } as const,
    ],
    query: { refetchInterval: 30000, enabled: addressesReady },
  });

  useEffect(() => {
    if (refreshTrigger) refetchChain();
  }, [refreshTrigger]);

  // Parse results with dynamic indices
  const totalPoolRaw    = chainData?.[0]?.result as bigint | undefined;
  const totalWeightsRaw = chainData?.[2 * N + 3]?.result as bigint | undefined;
  const totalPool       = totalPoolRaw    ? parseFloat(formatUnits(totalPoolRaw, 18))    : 0;
  const totalWeights    = totalWeightsRaw ? Number(totalWeightsRaw)                      : 0;

  const ytAllocations = ytTokens.map((token, i) => {
    const usdyRaw  = chainData?.[1 + i]?.result           as bigint | undefined;
    const priceRaw = chainData?.[N + 1 + i]?.result       as bigint | undefined;
    const twRaw    = chainData?.[2 * N + 4 + i]?.result   as bigint | undefined;

    const poolSizeUSD   = usdyRaw  ? parseFloat(formatUnits(usdyRaw, 18))   : 0;
    const ytPrice       = priceRaw ? parseFloat(formatUnits(priceRaw, 30))  : 0;
    const balance       = ytPrice > 0 ? poolSizeUSD / ytPrice : 0;
    const currentWeight = totalPool > 0 ? poolSizeUSD / totalPool * 100 : 0;
    const targetWeight  = totalWeights > 0 && twRaw != null ? Number(twRaw) / totalWeights * 100 : 0;

    return {
      key:           token.key,
      name:          token.meta?.name     ?? token.key,
      category:      token.meta?.category ?? '--',
      iconUrl:       token.meta?.iconUrl,
      poolSizeUSD,
      balance,
      ytPrice,
      currentWeight,
      targetWeight,
      isStable: false,
    };
  });

  const usdcRaw      = chainData?.[2 * N + 1]?.result as bigint | undefined;
  const usdcPriceRaw = chainData?.[2 * N + 2]?.result as bigint | undefined;
  const usdcTWRaw    = chainData?.[3 * N + 4]?.result as bigint | undefined;
  const usdcBalance  = usdcRaw      ? parseFloat(formatUnits(usdcRaw, 18))      : 0;
  const usdcPrice    = usdcPriceRaw ? parseFloat(formatUnits(usdcPriceRaw, 30)) : 0;
  const usdcPoolSize = usdcBalance * usdcPrice;
  const usdcCurWeight = totalPool > 0 ? usdcPoolSize / totalPool * 100 : 0;
  const usdcTgtWeight = totalWeights > 0 && usdcTWRaw != null ? Number(usdcTWRaw) / totalWeights * 100 : 0;
  const usdcMeta      = products.find((p: any) => p.tokenSymbol === 'USDC');

  const allocations = [
    ...ytAllocations,
    {
      key:           'USDC',
      name:          usdcMeta?.name     ?? 'USD Coin',
      category:      usdcMeta?.category ?? 'Stablecoin',
      iconUrl:       usdcMeta?.iconUrl,
      poolSizeUSD:   usdcPoolSize,
      balance:       usdcBalance,
      ytPrice:       usdcPrice,
      currentWeight: usdcCurWeight,
      targetWeight:  usdcTgtWeight,
      isStable:      true,
    },
  ];

  return (
    <div className="flex flex-col gap-3">
      {/* Title */}
      <h2 className="text-heading-h3 font-bold text-text-primary dark:text-white">
        {t("alp.liquidityAllocation")}
      </h2>

      {/* 移动端：卡片布局 */}
      <div className="md:hidden flex flex-col gap-3">
        {allocations.map((item) => (
          <div
            key={item.key}
            className="bg-bg-surface dark:bg-gray-800 rounded-2xl border border-border-gray dark:border-gray-700 p-4 flex flex-col gap-3"
          >
            {/* Token Header */}
            <div className="flex items-center gap-3">
              <Image
                src={item.iconUrl || '/assets/tokens/default.svg'}
                alt={item.key}
                width={36}
                height={36}
                className="rounded-full"
                onError={(e) => { (e.target as HTMLImageElement).src = '/assets/tokens/default.svg'; }}
              />
              <div className="flex flex-col">
                <span className="text-body-small font-bold text-text-primary dark:text-white">{item.name}</span>
                <span className="text-caption-tiny text-text-tertiary dark:text-gray-400">{item.category}</span>
              </div>
            </div>
            {/* Info Grid */}
            <div className="grid grid-cols-3 gap-2">
              <div className="flex flex-col gap-0.5">
                <span className="text-caption-tiny text-text-tertiary dark:text-gray-400">{t("alp.poolSize")}</span>
                <span className="text-body-small font-bold text-text-primary dark:text-white">
                  {item.poolSizeUSD > 0 ? formatUSD(item.poolSizeUSD) : '--'}
                </span>
                <span className="text-caption-tiny text-[#6b7280] dark:text-gray-400">
                  {item.balance > 0 ? `${item.balance.toFixed(2)} ${item.key}` : '--'}
                </span>
              </div>
              <div className="flex flex-col gap-0.5">
                <span className="text-caption-tiny text-text-tertiary dark:text-gray-400">Weight</span>
                <span className="text-body-small font-bold text-text-primary dark:text-white">
                  {totalPool > 0 ? `${item.currentWeight.toFixed(1)}%` : '--'}
                </span>
                <span className="text-caption-tiny text-text-tertiary dark:text-gray-400">
                  {item.targetWeight > 0 ? `→ ${item.targetWeight.toFixed(1)}%` : '--'}
                </span>
              </div>
              <div className="flex flex-col gap-0.5">
                <span className="text-caption-tiny text-text-tertiary dark:text-gray-400">{t("alp.currentPrice")}</span>
                <span className="text-body-small font-bold text-text-primary dark:text-white">
                  {item.ytPrice > 0 ? `$${item.ytPrice.toFixed(4)}` : '--'}
                </span>
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* 桌面端：表格布局 */}
      <div className="hidden md:block bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 overflow-hidden">
        <div className="flex flex-col">
          {/* Header */}
          <div className="flex border-b border-border-gray dark:border-gray-700 flex-shrink-0">
            <div className="flex-1 px-6 py-4">
              <div className="text-caption-tiny font-medium text-[#4b5563] dark:text-gray-400">{t("alp.token")}</div>
            </div>
            <div className="flex-1 px-6 py-4">
              <div className="text-caption-tiny font-medium text-[#4b5563] dark:text-gray-400">{t("alp.poolSize")}</div>
            </div>
            <div className="flex-1 px-6 py-4">
              <div className="text-caption-tiny font-medium text-[#4b5563] dark:text-gray-400">Weight (Current / Target)</div>
            </div>
            <div className="flex-1 px-6 py-4">
              <div className="text-caption-tiny font-medium text-[#4b5563] dark:text-gray-400">{t("alp.currentPrice")}</div>
            </div>
          </div>

          {/* Body */}
          {allocations.map((item) => (
            <div key={item.key} className="flex items-center border-b border-border-gray dark:border-gray-700 last:border-b-0">
              <div className="flex-1 px-6 py-4 flex items-center gap-3">
                <Image
                  src={item.iconUrl || '/assets/tokens/default.svg'}
                  alt={item.key}
                  width={32}
                  height={32}
                  className="rounded-full"
                  onError={(e) => { (e.target as HTMLImageElement).src = '/assets/tokens/default.svg'; }}
                />
                <div className="flex flex-col">
                  <span className="text-body-small font-bold text-text-primary dark:text-white">{item.name}</span>
                  <span className="text-caption-tiny font-regular text-text-tertiary dark:text-gray-400">{item.category}</span>
                </div>
              </div>
              <div className="flex-1 px-6 py-4">
                <div className="flex flex-col">
                  <span className="text-body-small font-bold text-text-primary dark:text-white">
                    {item.poolSizeUSD > 0 ? formatUSD(item.poolSizeUSD) : '--'}
                  </span>
                  <span className="text-caption-tiny font-regular text-[#6b7280] dark:text-gray-400">
                    {item.balance > 0 ? `${item.balance.toFixed(2)} ${item.key}` : '--'}
                  </span>
                </div>
              </div>
              <div className="flex-1 px-6 py-4">
                <span className="text-body-small font-bold text-text-primary dark:text-white">
                  {totalPool > 0 ? (
                    <>
                      {item.currentWeight.toFixed(1)}%
                      <span className="font-regular text-text-tertiary dark:text-gray-400">
                        {' / '}{item.targetWeight > 0 ? `${item.targetWeight.toFixed(1)}%` : '--'}
                      </span>
                    </>
                  ) : '--'}
                </span>
              </div>
              <div className="flex-1 px-6 py-4">
                <span className="text-body-small font-bold text-text-primary dark:text-white">
                  {item.ytPrice > 0 ? `$${item.ytPrice.toFixed(4)}` : '--'}
                </span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
