import { describe, expect, it, vi } from 'vitest'
import type { Block } from '@/services/api/blocks'
import type { ExplorerStats } from '@/services/api/stats'
import { loadDashboardData } from './dashboard'

const sampleStats: ExplorerStats = {
  total_blocks: 12,
  total_transactions: 34,
  total_addresses: 56,
  latest_block: 78,
}

const sampleBlocks: Block[] = [
  {
    chain_id: 138,
    number: 123,
    hash: '0xabc',
    timestamp: '2026-04-04T00:00:00.000Z',
    miner: '0xdef',
    transaction_count: 4,
    gas_used: 21000,
    gas_limit: 30000000,
  },
]

describe('loadDashboardData', () => {
  it('returns both stats and recent blocks when both loaders succeed', async () => {
    const result = await loadDashboardData({
      loadStats: async () => sampleStats,
      loadRecentBlocks: async () => sampleBlocks,
    })

    expect(result).toEqual({
      stats: sampleStats,
      recentBlocks: sampleBlocks,
      recentTransactionTrend: [],
    })
  })

  it('preserves recent blocks when stats loading fails', async () => {
    const onError = vi.fn()

    const result = await loadDashboardData({
      loadStats: async () => {
        throw new Error('stats unavailable')
      },
      loadRecentBlocks: async () => sampleBlocks,
      onError,
    })

    expect(result).toEqual({
      stats: null,
      recentBlocks: sampleBlocks,
      recentTransactionTrend: [],
    })
    expect(onError).toHaveBeenCalledTimes(1)
    expect(onError).toHaveBeenCalledWith('stats', expect.any(Error))
  })

  it('preserves stats when recent blocks loading fails', async () => {
    const onError = vi.fn()

    const result = await loadDashboardData({
      loadStats: async () => sampleStats,
      loadRecentBlocks: async () => {
        throw new Error('blocks unavailable')
      },
      onError,
    })

    expect(result).toEqual({
      stats: sampleStats,
      recentBlocks: [],
      recentTransactionTrend: [],
    })
    expect(onError).toHaveBeenCalledTimes(1)
    expect(onError).toHaveBeenCalledWith('blocks', expect.any(Error))
  })
})
