import { beforeEach, describe, expect, it, vi } from 'vitest'

import { tokensApi } from './tokens'

describe('tokensApi', () => {
  beforeEach(() => {
    vi.restoreAllMocks()
  })

  it('normalizes a token profile, holders, and transfers safely', async () => {
    const fetchMock = vi.fn()
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          address: '0xtoken',
          symbol: 'cUSDT',
          name: 'Tether USD (Compliant)',
          decimals: '6',
          holders: '37',
          total_supply: '1000',
        }),
      })
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          items: [
            {
              address: { hash: '0xholder', name: 'Treasury' },
              value: '500',
              token: { decimals: '6' },
            },
          ],
        }),
      })
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          items: [
            {
              transaction_hash: '0xtx',
              block_number: 1,
              from: { hash: '0xfrom' },
              to: { hash: '0xto' },
              token: {
                address: '0xtoken',
                symbol: 'cUSDT',
                name: 'Tether USD (Compliant)',
                decimals: '6',
              },
              total: { decimals: '6', value: '100' },
            },
          ],
        }),
      })

    vi.stubGlobal('fetch', fetchMock)

    const token = await tokensApi.getSafe('0xtoken')
    const holders = await tokensApi.getHoldersSafe('0xtoken')
    const transfers = await tokensApi.getTransfersSafe('0xtoken')

    expect(token.ok).toBe(true)
    expect(token.data?.symbol).toBe('cUSDT')
    expect(holders.data[0].label).toBe('Treasury')
    expect(transfers.data[0].token_symbol).toBe('cUSDT')
  })

  it('builds provenance and curated token lists from the token list config', async () => {
    const fetchMock = vi.fn()
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          tokens: [
            {
              chainId: 138,
              address: '0xlisted',
              symbol: 'cUSDT',
              name: 'Tether USD (Compliant)',
              tags: ['compliant', 'bridge'],
            },
            {
              chainId: 1,
              address: '0xother',
              symbol: 'OTHER',
            },
          ],
        }),
      })
      .mockResolvedValueOnce({
        ok: true,
        json: async () => ({
          tokens: [
            {
              chainId: 138,
              address: '0xlisted',
              symbol: 'cUSDT',
              name: 'Tether USD (Compliant)',
              tags: ['compliant', 'bridge'],
            },
          ],
        }),
      })

    vi.stubGlobal('fetch', fetchMock)

    const provenance = await tokensApi.getProvenanceSafe('0xlisted')
    const curated = await tokensApi.listCuratedSafe(138)

    expect(provenance.ok).toBe(true)
    expect(provenance.data?.listed).toBe(true)
    expect(provenance.data?.tags).toEqual(['compliant', 'bridge'])
    expect(curated.data).toHaveLength(1)
    expect(curated.data[0].symbol).toBe('cUSDT')
  })
})
