import express from 'express';
import metamaskPriceRoutes from './metamask-prices';
import { primeLiveReferencePriceUsd } from '../../services/canonical-price-oracle';

jest.mock('../middleware/cache', () => ({
  cacheMiddleware: () => (_req: unknown, _res: unknown, next: () => void) => next(),
}));

jest.mock('../../services/iso4217-fx-refresh', () => ({
  ensureIso4217FxPrimed: jest.fn().mockResolvedValue(undefined),
}));

jest.mock('../../services/chain138-onchain-reference-prices', () => ({
  refreshChain138LiveReferencePrices: jest.fn().mockResolvedValue(undefined),
  getChain138EthUsdOnChain: jest.fn().mockResolvedValue({ priceUsd: 1772, source: 'aggregator' }),
}));

describe('metamask spot prices API', () => {
  let baseUrl = '';
  let server: ReturnType<express.Application['listen']> | null = null;

  beforeAll(async () => {
    process.env.TOKEN_AGGREGATION_SKIP_DB_READS = '1';
    primeLiveReferencePriceUsd('USD', 1);
    primeLiveReferencePriceUsd('AUD', 0.71);

    const app = express();
    app.use('/api/v1/prices/metamask', metamaskPriceRoutes);
    await new Promise<void>((resolve) => {
      server = app.listen(0, () => {
        const address = server?.address();
        const port = typeof address === 'object' && address ? address.port : 0;
        baseUrl = `http://127.0.0.1:${port}/api/v1/prices/metamask`;
        resolve();
      });
    });
  });

  afterAll(async () => {
    await new Promise<void>((resolve, reject) => {
      if (!server) {
        resolve();
        return;
      }
      server.close((error) => (error ? reject(error) : resolve()));
    });
  });

  it('returns MetaMask v2 spot price map for WETH via native oracle on chain 138', async () => {
    const address = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
    const res = await fetch(
      `${baseUrl}/v2/chains/138/spot-prices?tokenAddresses=${address}&vsCurrency=usd`,
    );
    expect(res.status).toBe(200);
    const body = (await res.json()) as Record<string, { usd?: number }>;
    expect(body[address]?.usd).toBe(1772);
  });

  it('returns MetaMask v2 spot price map for canonical cUSDC', async () => {
    const address = '0xf22258f57794cc8e06237084b353ab30fffa640b';
    const res = await fetch(
      `${baseUrl}/v2/chains/138/spot-prices?tokenAddresses=${address}&vsCurrency=usd`,
    );
    expect(res.status).toBe(200);
    const body = (await res.json()) as Record<string, { usd?: number }>;
    expect(body[address]?.usd).toBeGreaterThan(0);
  });
});
