import type { ResolvedTokenDisplay } from './token-display';
import { classifyPoolDepthStatus, estimateChain138FallbackDepthUsd } from './route-decision-tree';

function token(address: string, symbol: string, decimals: number): ResolvedTokenDisplay {
  return {
    address,
    symbol,
    name: symbol,
    decimals,
    source: 'canonical',
  };
}

describe('estimateChain138FallbackDepthUsd', () => {
  it('derives tvl from the stable side for funded mixed pairs', () => {
    const weth10 = token('0xf4bb2e28688e89fcce3c0580d37d36a7672e8a9f', 'WETH10', 18);
    const usdt = token('0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1', 'USDT', 6);

    const result = estimateChain138FallbackDepthUsd(
      weth10,
      50n * 10n ** 18n,
      usdt,
      200_000n * 10n ** 6n
    );

    expect(result.tvlUsd).toBe(400_000);
    expect(result.estimatedTradeCapacityUsd).toBe(80_000);
  });

  it('adds both sides for funded stable-to-stable pools', () => {
    const cusdcV2 = token('0x219522c60e83dEe01FC5b0329d6fA8fD84b9D13d', 'cUSDC_V2', 6);
    const usdc = token('0x71D6687F38b93CCad569Fa6352c876eea967201b', 'USDC', 6);

    const result = estimateChain138FallbackDepthUsd(
      cusdcV2,
      1_000_000n * 10n ** 6n,
      usdc,
      1_000_000n * 10n ** 6n
    );

    expect(result.tvlUsd).toBe(2_000_000);
    expect(result.estimatedTradeCapacityUsd).toBe(400_000);
  });

  it('keeps zero-dollar metrics for non-stable or partially funded pools', () => {
    const weth = token('0xf4bb2e28688e89fcce3c0580d37d36a7672e8a9f', 'WETH10', 18);
    const cxauc = token('0x290E52a8819A4fbD0714E517225429aA2B70EC6b', 'cXAUC', 18);

    expect(
      estimateChain138FallbackDepthUsd(weth, 10n * 10n ** 18n, cxauc, 5n * 10n ** 18n)
    ).toEqual({
      tvlUsd: 0,
      estimatedTradeCapacityUsd: 0,
    });

    expect(
      estimateChain138FallbackDepthUsd(weth, 10n * 10n ** 18n, token('0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1', 'USDT', 6), 0n)
    ).toEqual({
      tvlUsd: 0,
      estimatedTradeCapacityUsd: 0,
    });
  });
});

describe('classifyPoolDepthStatus', () => {
  it('marks zero-liquidity pools unavailable even if freshness is recent', () => {
    expect(classifyPoolDepthStatus(0, 0, 0)).toBe('unavailable');
    expect(classifyPoolDepthStatus(1000, 0, 120)).toBe('unavailable');
  });

  it('keeps funded pools live or stale based on freshness', () => {
    expect(classifyPoolDepthStatus(1000, 200, 60)).toBe('live');
    expect(classifyPoolDepthStatus(1000, 200, 900)).toBe('stale');
    expect(classifyPoolDepthStatus(1000, 200, 3600)).toBe('unavailable');
  });
});
